xref: /vim-8.2.3635/src/ex_cmds2.c (revision e16b00a1)
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  * ex_cmds2.c: some more functions for command line commands
12  */
13 
14 #include "vim.h"
15 #include "version.h"
16 
17 static void	cmd_source(char_u *fname, exarg_T *eap);
18 
19 #ifdef FEAT_EVAL
20 /* Growarray to store info about already sourced scripts.
21  * For Unix also store the dev/ino, so that we don't have to stat() each
22  * script when going through the list. */
23 typedef struct scriptitem_S
24 {
25     char_u	*sn_name;
26 # ifdef UNIX
27     int		sn_dev_valid;
28     dev_t	sn_dev;
29     ino_t	sn_ino;
30 # endif
31 # ifdef FEAT_PROFILE
32     int		sn_prof_on;	/* TRUE when script is/was profiled */
33     int		sn_pr_force;	/* forceit: profile functions in this script */
34     proftime_T	sn_pr_child;	/* time set when going into first child */
35     int		sn_pr_nest;	/* nesting for sn_pr_child */
36     /* profiling the script as a whole */
37     int		sn_pr_count;	/* nr of times sourced */
38     proftime_T	sn_pr_total;	/* time spent in script + children */
39     proftime_T	sn_pr_self;	/* time spent in script itself */
40     proftime_T	sn_pr_start;	/* time at script start */
41     proftime_T	sn_pr_children; /* time in children after script start */
42     /* profiling the script per line */
43     garray_T	sn_prl_ga;	/* things stored for every line */
44     proftime_T	sn_prl_start;	/* start time for current line */
45     proftime_T	sn_prl_children; /* time spent in children for this line */
46     proftime_T	sn_prl_wait;	/* wait start time for current line */
47     int		sn_prl_idx;	/* index of line being timed; -1 if none */
48     int		sn_prl_execed;	/* line being timed was executed */
49 # endif
50 } scriptitem_T;
51 
52 static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL};
53 #define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
54 
55 # ifdef FEAT_PROFILE
56 /* Struct used in sn_prl_ga for every line of a script. */
57 typedef struct sn_prl_S
58 {
59     int		snp_count;	/* nr of times line was executed */
60     proftime_T	sn_prl_total;	/* time spent in a line + children */
61     proftime_T	sn_prl_self;	/* time spent in a line itself */
62 } sn_prl_T;
63 
64 #  define PRL_ITEM(si, idx)	(((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
65 # endif
66 #endif
67 
68 #if defined(FEAT_EVAL) || defined(PROTO)
69 static int debug_greedy = FALSE;	/* batch mode debugging: don't save
70 					   and restore typeahead. */
71 static int get_maxbacktrace_level(void);
72 static void do_setdebugtracelevel(char_u *arg);
73 static void do_checkbacktracelevel(void);
74 static void do_showbacktrace(char_u *cmd);
75 
76 /*
77  * do_debug(): Debug mode.
78  * Repeatedly get Ex commands, until told to continue normal execution.
79  */
80     void
81 do_debug(char_u *cmd)
82 {
83     int		save_msg_scroll = msg_scroll;
84     int		save_State = State;
85     int		save_did_emsg = did_emsg;
86     int		save_cmd_silent = cmd_silent;
87     int		save_msg_silent = msg_silent;
88     int		save_emsg_silent = emsg_silent;
89     int		save_redir_off = redir_off;
90     tasave_T	typeaheadbuf;
91     int		typeahead_saved = FALSE;
92     int		save_ignore_script = 0;
93     int		save_ex_normal_busy;
94     int		n;
95     char_u	*cmdline = NULL;
96     char_u	*p;
97     char	*tail = NULL;
98     static int	last_cmd = 0;
99 #define CMD_CONT	1
100 #define CMD_NEXT	2
101 #define CMD_STEP	3
102 #define CMD_FINISH	4
103 #define CMD_QUIT	5
104 #define CMD_INTERRUPT	6
105 #define CMD_BACKTRACE	7
106 #define CMD_FRAME	8
107 #define CMD_UP		9
108 #define CMD_DOWN	10
109 
110 #ifdef ALWAYS_USE_GUI
111     /* Can't do this when there is no terminal for input/output. */
112     if (!gui.in_use)
113     {
114 	/* Break as soon as possible. */
115 	debug_break_level = 9999;
116 	return;
117     }
118 #endif
119 
120     /* Make sure we are in raw mode and start termcap mode.  Might have side
121      * effects... */
122     settmode(TMODE_RAW);
123     starttermcap();
124 
125     ++RedrawingDisabled;	/* don't redisplay the window */
126     ++no_wait_return;		/* don't wait for return */
127     did_emsg = FALSE;		/* don't use error from debugged stuff */
128     cmd_silent = FALSE;		/* display commands */
129     msg_silent = FALSE;		/* display messages */
130     emsg_silent = FALSE;	/* display error messages */
131     redir_off = TRUE;		/* don't redirect debug commands */
132 
133     State = NORMAL;
134 
135     if (!debug_did_msg)
136 	MSG(_("Entering Debug mode.  Type \"cont\" to continue."));
137     if (sourcing_name != NULL)
138 	msg(sourcing_name);
139     if (sourcing_lnum != 0)
140 	smsg((char_u *)_("line %ld: %s"), (long)sourcing_lnum, cmd);
141     else
142 	smsg((char_u *)_("cmd: %s"), cmd);
143 
144     /*
145      * Repeat getting a command and executing it.
146      */
147     for (;;)
148     {
149 	msg_scroll = TRUE;
150 	need_wait_return = FALSE;
151 
152 	/* Save the current typeahead buffer and replace it with an empty one.
153 	 * This makes sure we get input from the user here and don't interfere
154 	 * with the commands being executed.  Reset "ex_normal_busy" to avoid
155 	 * the side effects of using ":normal". Save the stuff buffer and make
156 	 * it empty. Set ignore_script to avoid reading from script input. */
157 	save_ex_normal_busy = ex_normal_busy;
158 	ex_normal_busy = 0;
159 	if (!debug_greedy)
160 	{
161 	    save_typeahead(&typeaheadbuf);
162 	    typeahead_saved = TRUE;
163 	    save_ignore_script = ignore_script;
164 	    ignore_script = TRUE;
165 	}
166 
167 	vim_free(cmdline);
168 	cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
169 
170 	if (typeahead_saved)
171 	{
172 	    restore_typeahead(&typeaheadbuf);
173 	    ignore_script = save_ignore_script;
174 	}
175 	ex_normal_busy = save_ex_normal_busy;
176 
177 	cmdline_row = msg_row;
178 	msg_starthere();
179 	if (cmdline != NULL)
180 	{
181 	    /* If this is a debug command, set "last_cmd".
182 	     * If not, reset "last_cmd".
183 	     * For a blank line use previous command. */
184 	    p = skipwhite(cmdline);
185 	    if (*p != NUL)
186 	    {
187 		switch (*p)
188 		{
189 		    case 'c': last_cmd = CMD_CONT;
190 			      tail = "ont";
191 			      break;
192 		    case 'n': last_cmd = CMD_NEXT;
193 			      tail = "ext";
194 			      break;
195 		    case 's': last_cmd = CMD_STEP;
196 			      tail = "tep";
197 			      break;
198 		    case 'f':
199 			      last_cmd = 0;
200 			      if (p[1] == 'r')
201 			      {
202 				  last_cmd = CMD_FRAME;
203 				  tail = "rame";
204 			      }
205 			      else
206 			      {
207 				  last_cmd = CMD_FINISH;
208 				  tail = "inish";
209 			      }
210 			      break;
211 		    case 'q': last_cmd = CMD_QUIT;
212 			      tail = "uit";
213 			      break;
214 		    case 'i': last_cmd = CMD_INTERRUPT;
215 			      tail = "nterrupt";
216 			      break;
217 		    case 'b': last_cmd = CMD_BACKTRACE;
218 			      if (p[1] == 't')
219 				  tail = "t";
220 			      else
221 				  tail = "acktrace";
222 			      break;
223 		    case 'w': last_cmd = CMD_BACKTRACE;
224 			      tail = "here";
225 			      break;
226 		    case 'u': last_cmd = CMD_UP;
227 			      tail = "p";
228 			      break;
229 		    case 'd': last_cmd = CMD_DOWN;
230 			      tail = "own";
231 			      break;
232 		    default: last_cmd = 0;
233 		}
234 		if (last_cmd != 0)
235 		{
236 		    /* Check that the tail matches. */
237 		    ++p;
238 		    while (*p != NUL && *p == *tail)
239 		    {
240 			++p;
241 			++tail;
242 		    }
243 		    if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME)
244 			last_cmd = 0;
245 		}
246 	    }
247 
248 	    if (last_cmd != 0)
249 	    {
250 		/* Execute debug command: decided where to break next and
251 		 * return. */
252 		switch (last_cmd)
253 		{
254 		    case CMD_CONT:
255 			debug_break_level = -1;
256 			break;
257 		    case CMD_NEXT:
258 			debug_break_level = ex_nesting_level;
259 			break;
260 		    case CMD_STEP:
261 			debug_break_level = 9999;
262 			break;
263 		    case CMD_FINISH:
264 			debug_break_level = ex_nesting_level - 1;
265 			break;
266 		    case CMD_QUIT:
267 			got_int = TRUE;
268 			debug_break_level = -1;
269 			break;
270 		    case CMD_INTERRUPT:
271 			got_int = TRUE;
272 			debug_break_level = 9999;
273 			/* Do not repeat ">interrupt" cmd, continue stepping. */
274 			last_cmd = CMD_STEP;
275 			break;
276 		    case CMD_BACKTRACE:
277 			do_showbacktrace(cmd);
278 			continue;
279 		    case CMD_FRAME:
280 			if (*p == NUL)
281 			{
282 			    do_showbacktrace(cmd);
283 			}
284 			else
285 			{
286 			    p = skipwhite(p);
287 			    do_setdebugtracelevel(p);
288 			}
289 			continue;
290 		    case CMD_UP:
291 			debug_backtrace_level++;
292 			do_checkbacktracelevel();
293 			continue;
294 		    case CMD_DOWN:
295 			debug_backtrace_level--;
296 			do_checkbacktracelevel();
297 			continue;
298 		}
299 		/* Going out reset backtrace_level */
300 		debug_backtrace_level = 0;
301 		break;
302 	    }
303 
304 	    /* don't debug this command */
305 	    n = debug_break_level;
306 	    debug_break_level = -1;
307 	    (void)do_cmdline(cmdline, getexline, NULL,
308 						DOCMD_VERBOSE|DOCMD_EXCRESET);
309 	    debug_break_level = n;
310 	}
311 	lines_left = Rows - 1;
312     }
313     vim_free(cmdline);
314 
315     --RedrawingDisabled;
316     --no_wait_return;
317     redraw_all_later(NOT_VALID);
318     need_wait_return = FALSE;
319     msg_scroll = save_msg_scroll;
320     lines_left = Rows - 1;
321     State = save_State;
322     did_emsg = save_did_emsg;
323     cmd_silent = save_cmd_silent;
324     msg_silent = save_msg_silent;
325     emsg_silent = save_emsg_silent;
326     redir_off = save_redir_off;
327 
328     /* Only print the message again when typing a command before coming back
329      * here. */
330     debug_did_msg = TRUE;
331 }
332 
333     static int
334 get_maxbacktrace_level(void)
335 {
336     char	*p, *q;
337     int		maxbacktrace = 0;
338 
339     if (sourcing_name != NULL)
340     {
341 	p = (char *)sourcing_name;
342 	while ((q = strstr(p, "..")) != NULL)
343 	{
344 	    p = q + 2;
345 	    maxbacktrace++;
346 	}
347     }
348     return maxbacktrace;
349 }
350 
351     static void
352 do_setdebugtracelevel(char_u *arg)
353 {
354     int level;
355 
356     level = atoi((char *)arg);
357     if (*arg == '+' || level < 0)
358 	debug_backtrace_level += level;
359     else
360 	debug_backtrace_level = level;
361 
362     do_checkbacktracelevel();
363 }
364 
365     static void
366 do_checkbacktracelevel(void)
367 {
368     if (debug_backtrace_level < 0)
369     {
370 	debug_backtrace_level = 0;
371 	MSG(_("frame is zero"));
372     }
373     else
374     {
375 	int max = get_maxbacktrace_level();
376 
377 	if (debug_backtrace_level > max)
378 	{
379 	    debug_backtrace_level = max;
380 	    smsg((char_u *)_("frame at highest level: %d"), max);
381 	}
382     }
383 }
384 
385     static void
386 do_showbacktrace(char_u *cmd)
387 {
388     char    *cur;
389     char    *next;
390     int	    i = 0;
391     int	    max = get_maxbacktrace_level();
392 
393     if (sourcing_name != NULL)
394     {
395 	cur = (char *)sourcing_name;
396 	while (!got_int)
397 	{
398 	    next = strstr(cur, "..");
399 	    if (next != NULL)
400 		*next = NUL;
401 	    if (i == max - debug_backtrace_level)
402 		smsg((char_u *)"->%d %s", max - i, cur);
403 	    else
404 		smsg((char_u *)"  %d %s", max - i, cur);
405 	    ++i;
406 	    if (next == NULL)
407 		break;
408 	    *next = '.';
409 	    cur = next + 2;
410 	}
411     }
412     if (sourcing_lnum != 0)
413        smsg((char_u *)_("line %ld: %s"), (long)sourcing_lnum, cmd);
414     else
415        smsg((char_u *)_("cmd: %s"), cmd);
416 }
417 
418 /*
419  * ":debug".
420  */
421     void
422 ex_debug(exarg_T *eap)
423 {
424     int		debug_break_level_save = debug_break_level;
425 
426     debug_break_level = 9999;
427     do_cmdline_cmd(eap->arg);
428     debug_break_level = debug_break_level_save;
429 }
430 
431 static char_u	*debug_breakpoint_name = NULL;
432 static linenr_T	debug_breakpoint_lnum;
433 
434 /*
435  * When debugging or a breakpoint is set on a skipped command, no debug prompt
436  * is shown by do_one_cmd().  This situation is indicated by debug_skipped, and
437  * debug_skipped_name is then set to the source name in the breakpoint case.  If
438  * a skipped command decides itself that a debug prompt should be displayed, it
439  * can do so by calling dbg_check_skipped().
440  */
441 static int	debug_skipped;
442 static char_u	*debug_skipped_name;
443 
444 /*
445  * Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is
446  * at or below the break level.  But only when the line is actually
447  * executed.  Return TRUE and set breakpoint_name for skipped commands that
448  * decide to execute something themselves.
449  * Called from do_one_cmd() before executing a command.
450  */
451     void
452 dbg_check_breakpoint(exarg_T *eap)
453 {
454     char_u	*p;
455 
456     debug_skipped = FALSE;
457     if (debug_breakpoint_name != NULL)
458     {
459 	if (!eap->skip)
460 	{
461 	    /* replace K_SNR with "<SNR>" */
462 	    if (debug_breakpoint_name[0] == K_SPECIAL
463 		    && debug_breakpoint_name[1] == KS_EXTRA
464 		    && debug_breakpoint_name[2] == (int)KE_SNR)
465 		p = (char_u *)"<SNR>";
466 	    else
467 		p = (char_u *)"";
468 	    smsg((char_u *)_("Breakpoint in \"%s%s\" line %ld"),
469 		    p,
470 		    debug_breakpoint_name + (*p == NUL ? 0 : 3),
471 		    (long)debug_breakpoint_lnum);
472 	    debug_breakpoint_name = NULL;
473 	    do_debug(eap->cmd);
474 	}
475 	else
476 	{
477 	    debug_skipped = TRUE;
478 	    debug_skipped_name = debug_breakpoint_name;
479 	    debug_breakpoint_name = NULL;
480 	}
481     }
482     else if (ex_nesting_level <= debug_break_level)
483     {
484 	if (!eap->skip)
485 	    do_debug(eap->cmd);
486 	else
487 	{
488 	    debug_skipped = TRUE;
489 	    debug_skipped_name = NULL;
490 	}
491     }
492 }
493 
494 /*
495  * Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was
496  * set.  Return TRUE when the debug mode is entered this time.
497  */
498     int
499 dbg_check_skipped(exarg_T *eap)
500 {
501     int		prev_got_int;
502 
503     if (debug_skipped)
504     {
505 	/*
506 	 * Save the value of got_int and reset it.  We don't want a previous
507 	 * interruption cause flushing the input buffer.
508 	 */
509 	prev_got_int = got_int;
510 	got_int = FALSE;
511 	debug_breakpoint_name = debug_skipped_name;
512 	/* eap->skip is TRUE */
513 	eap->skip = FALSE;
514 	(void)dbg_check_breakpoint(eap);
515 	eap->skip = TRUE;
516 	got_int |= prev_got_int;
517 	return TRUE;
518     }
519     return FALSE;
520 }
521 
522 /*
523  * The list of breakpoints: dbg_breakp.
524  * This is a grow-array of structs.
525  */
526 struct debuggy
527 {
528     int		dbg_nr;		/* breakpoint number */
529     int		dbg_type;	/* DBG_FUNC or DBG_FILE */
530     char_u	*dbg_name;	/* function or file name */
531     regprog_T	*dbg_prog;	/* regexp program */
532     linenr_T	dbg_lnum;	/* line number in function or file */
533     int		dbg_forceit;	/* ! used */
534 };
535 
536 static garray_T dbg_breakp = {0, 0, sizeof(struct debuggy), 4, NULL};
537 #define BREAKP(idx)		(((struct debuggy *)dbg_breakp.ga_data)[idx])
538 #define DEBUGGY(gap, idx)	(((struct debuggy *)gap->ga_data)[idx])
539 static int last_breakp = 0;	/* nr of last defined breakpoint */
540 
541 #ifdef FEAT_PROFILE
542 /* Profiling uses file and func names similar to breakpoints. */
543 static garray_T prof_ga = {0, 0, sizeof(struct debuggy), 4, NULL};
544 #endif
545 #define DBG_FUNC	1
546 #define DBG_FILE	2
547 
548 static int dbg_parsearg(char_u *arg, garray_T *gap);
549 static linenr_T debuggy_find(int file,char_u *fname, linenr_T after, garray_T *gap, int *fp);
550 
551 /*
552  * Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
553  * in the entry just after the last one in dbg_breakp.  Note that "dbg_name"
554  * is allocated.
555  * Returns FAIL for failure.
556  */
557     static int
558 dbg_parsearg(
559     char_u	*arg,
560     garray_T	*gap)	    /* either &dbg_breakp or &prof_ga */
561 {
562     char_u	*p = arg;
563     char_u	*q;
564     struct debuggy *bp;
565     int		here = FALSE;
566 
567     if (ga_grow(gap, 1) == FAIL)
568 	return FAIL;
569     bp = &DEBUGGY(gap, gap->ga_len);
570 
571     /* Find "func" or "file". */
572     if (STRNCMP(p, "func", 4) == 0)
573 	bp->dbg_type = DBG_FUNC;
574     else if (STRNCMP(p, "file", 4) == 0)
575 	bp->dbg_type = DBG_FILE;
576     else if (
577 #ifdef FEAT_PROFILE
578 	    gap != &prof_ga &&
579 #endif
580 	    STRNCMP(p, "here", 4) == 0)
581     {
582 	if (curbuf->b_ffname == NULL)
583 	{
584 	    EMSG(_(e_noname));
585 	    return FAIL;
586 	}
587 	bp->dbg_type = DBG_FILE;
588 	here = TRUE;
589     }
590     else
591     {
592 	EMSG2(_(e_invarg2), p);
593 	return FAIL;
594     }
595     p = skipwhite(p + 4);
596 
597     /* Find optional line number. */
598     if (here)
599 	bp->dbg_lnum = curwin->w_cursor.lnum;
600     else if (
601 #ifdef FEAT_PROFILE
602 	    gap != &prof_ga &&
603 #endif
604 	    VIM_ISDIGIT(*p))
605     {
606 	bp->dbg_lnum = getdigits(&p);
607 	p = skipwhite(p);
608     }
609     else
610 	bp->dbg_lnum = 0;
611 
612     /* Find the function or file name.  Don't accept a function name with (). */
613     if ((!here && *p == NUL)
614 	    || (here && *p != NUL)
615 	    || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL))
616     {
617 	EMSG2(_(e_invarg2), arg);
618 	return FAIL;
619     }
620 
621     if (bp->dbg_type == DBG_FUNC)
622 	bp->dbg_name = vim_strsave(p);
623     else if (here)
624 	bp->dbg_name = vim_strsave(curbuf->b_ffname);
625     else
626     {
627 	/* Expand the file name in the same way as do_source().  This means
628 	 * doing it twice, so that $DIR/file gets expanded when $DIR is
629 	 * "~/dir". */
630 	q = expand_env_save(p);
631 	if (q == NULL)
632 	    return FAIL;
633 	p = expand_env_save(q);
634 	vim_free(q);
635 	if (p == NULL)
636 	    return FAIL;
637 	if (*p != '*')
638 	{
639 	    bp->dbg_name = fix_fname(p);
640 	    vim_free(p);
641 	}
642 	else
643 	    bp->dbg_name = p;
644     }
645 
646     if (bp->dbg_name == NULL)
647 	return FAIL;
648     return OK;
649 }
650 
651 /*
652  * ":breakadd".
653  */
654     void
655 ex_breakadd(exarg_T *eap)
656 {
657     struct debuggy *bp;
658     char_u	*pat;
659     garray_T	*gap;
660 
661     gap = &dbg_breakp;
662 #ifdef FEAT_PROFILE
663     if (eap->cmdidx == CMD_profile)
664 	gap = &prof_ga;
665 #endif
666 
667     if (dbg_parsearg(eap->arg, gap) == OK)
668     {
669 	bp = &DEBUGGY(gap, gap->ga_len);
670 	bp->dbg_forceit = eap->forceit;
671 
672 	pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, FALSE);
673 	if (pat != NULL)
674 	{
675 	    bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
676 	    vim_free(pat);
677 	}
678 	if (pat == NULL || bp->dbg_prog == NULL)
679 	    vim_free(bp->dbg_name);
680 	else
681 	{
682 	    if (bp->dbg_lnum == 0)	/* default line number is 1 */
683 		bp->dbg_lnum = 1;
684 #ifdef FEAT_PROFILE
685 	    if (eap->cmdidx != CMD_profile)
686 #endif
687 	    {
688 		DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
689 		++debug_tick;
690 	    }
691 	    ++gap->ga_len;
692 	}
693     }
694 }
695 
696 /*
697  * ":debuggreedy".
698  */
699     void
700 ex_debuggreedy(exarg_T *eap)
701 {
702     if (eap->addr_count == 0 || eap->line2 != 0)
703 	debug_greedy = TRUE;
704     else
705 	debug_greedy = FALSE;
706 }
707 
708 /*
709  * ":breakdel" and ":profdel".
710  */
711     void
712 ex_breakdel(exarg_T *eap)
713 {
714     struct debuggy *bp, *bpi;
715     int		nr;
716     int		todel = -1;
717     int		del_all = FALSE;
718     int		i;
719     linenr_T	best_lnum = 0;
720     garray_T	*gap;
721 
722     gap = &dbg_breakp;
723     if (eap->cmdidx == CMD_profdel)
724     {
725 #ifdef FEAT_PROFILE
726 	gap = &prof_ga;
727 #else
728 	ex_ni(eap);
729 	return;
730 #endif
731     }
732 
733     if (vim_isdigit(*eap->arg))
734     {
735 	/* ":breakdel {nr}" */
736 	nr = atol((char *)eap->arg);
737 	for (i = 0; i < gap->ga_len; ++i)
738 	    if (DEBUGGY(gap, i).dbg_nr == nr)
739 	    {
740 		todel = i;
741 		break;
742 	    }
743     }
744     else if (*eap->arg == '*')
745     {
746 	todel = 0;
747 	del_all = TRUE;
748     }
749     else
750     {
751 	/* ":breakdel {func|file} [lnum] {name}" */
752 	if (dbg_parsearg(eap->arg, gap) == FAIL)
753 	    return;
754 	bp = &DEBUGGY(gap, gap->ga_len);
755 	for (i = 0; i < gap->ga_len; ++i)
756 	{
757 	    bpi = &DEBUGGY(gap, i);
758 	    if (bp->dbg_type == bpi->dbg_type
759 		    && STRCMP(bp->dbg_name, bpi->dbg_name) == 0
760 		    && (bp->dbg_lnum == bpi->dbg_lnum
761 			|| (bp->dbg_lnum == 0
762 			    && (best_lnum == 0
763 				|| bpi->dbg_lnum < best_lnum))))
764 	    {
765 		todel = i;
766 		best_lnum = bpi->dbg_lnum;
767 	    }
768 	}
769 	vim_free(bp->dbg_name);
770     }
771 
772     if (todel < 0)
773 	EMSG2(_("E161: Breakpoint not found: %s"), eap->arg);
774     else
775     {
776 	while (gap->ga_len > 0)
777 	{
778 	    vim_free(DEBUGGY(gap, todel).dbg_name);
779 	    vim_regfree(DEBUGGY(gap, todel).dbg_prog);
780 	    --gap->ga_len;
781 	    if (todel < gap->ga_len)
782 		mch_memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1),
783 			      (gap->ga_len - todel) * sizeof(struct debuggy));
784 #ifdef FEAT_PROFILE
785 	    if (eap->cmdidx == CMD_breakdel)
786 #endif
787 		++debug_tick;
788 	    if (!del_all)
789 		break;
790 	}
791 
792 	/* If all breakpoints were removed clear the array. */
793 	if (gap->ga_len == 0)
794 	    ga_clear(gap);
795     }
796 }
797 
798 /*
799  * ":breaklist".
800  */
801     void
802 ex_breaklist(exarg_T *eap UNUSED)
803 {
804     struct debuggy *bp;
805     int		i;
806 
807     if (dbg_breakp.ga_len == 0)
808 	MSG(_("No breakpoints defined"));
809     else
810 	for (i = 0; i < dbg_breakp.ga_len; ++i)
811 	{
812 	    bp = &BREAKP(i);
813 	    if (bp->dbg_type == DBG_FILE)
814 		home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, TRUE);
815 	    smsg((char_u *)_("%3d  %s %s  line %ld"),
816 		    bp->dbg_nr,
817 		    bp->dbg_type == DBG_FUNC ? "func" : "file",
818 		    bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff,
819 		    (long)bp->dbg_lnum);
820 	}
821 }
822 
823 /*
824  * Find a breakpoint for a function or sourced file.
825  * Returns line number at which to break; zero when no matching breakpoint.
826  */
827     linenr_T
828 dbg_find_breakpoint(
829     int		file,	    /* TRUE for a file, FALSE for a function */
830     char_u	*fname,	    /* file or function name */
831     linenr_T	after)	    /* after this line number */
832 {
833     return debuggy_find(file, fname, after, &dbg_breakp, NULL);
834 }
835 
836 #if defined(FEAT_PROFILE) || defined(PROTO)
837 /*
838  * Return TRUE if profiling is on for a function or sourced file.
839  */
840     int
841 has_profiling(
842     int		file,	    /* TRUE for a file, FALSE for a function */
843     char_u	*fname,	    /* file or function name */
844     int		*fp)	    /* return: forceit */
845 {
846     return (debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
847 							      != (linenr_T)0);
848 }
849 #endif
850 
851 /*
852  * Common code for dbg_find_breakpoint() and has_profiling().
853  */
854     static linenr_T
855 debuggy_find(
856     int		file,	    /* TRUE for a file, FALSE for a function */
857     char_u	*fname,	    /* file or function name */
858     linenr_T	after,	    /* after this line number */
859     garray_T	*gap,	    /* either &dbg_breakp or &prof_ga */
860     int		*fp)	    /* if not NULL: return forceit */
861 {
862     struct debuggy *bp;
863     int		i;
864     linenr_T	lnum = 0;
865     char_u	*name = fname;
866     int		prev_got_int;
867 
868     /* Return quickly when there are no breakpoints. */
869     if (gap->ga_len == 0)
870 	return (linenr_T)0;
871 
872     /* Replace K_SNR in function name with "<SNR>". */
873     if (!file && fname[0] == K_SPECIAL)
874     {
875 	name = alloc((unsigned)STRLEN(fname) + 3);
876 	if (name == NULL)
877 	    name = fname;
878 	else
879 	{
880 	    STRCPY(name, "<SNR>");
881 	    STRCPY(name + 5, fname + 3);
882 	}
883     }
884 
885     for (i = 0; i < gap->ga_len; ++i)
886     {
887 	/* Skip entries that are not useful or are for a line that is beyond
888 	 * an already found breakpoint. */
889 	bp = &DEBUGGY(gap, i);
890 	if (((bp->dbg_type == DBG_FILE) == file && (
891 #ifdef FEAT_PROFILE
892 		gap == &prof_ga ||
893 #endif
894 		(bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))))
895 	{
896 	    /*
897 	     * Save the value of got_int and reset it.  We don't want a
898 	     * previous interruption cancel matching, only hitting CTRL-C
899 	     * while matching should abort it.
900 	     */
901 	    prev_got_int = got_int;
902 	    got_int = FALSE;
903 	    if (vim_regexec_prog(&bp->dbg_prog, FALSE, name, (colnr_T)0))
904 	    {
905 		lnum = bp->dbg_lnum;
906 		if (fp != NULL)
907 		    *fp = bp->dbg_forceit;
908 	    }
909 	    got_int |= prev_got_int;
910 	}
911     }
912     if (name != fname)
913 	vim_free(name);
914 
915     return lnum;
916 }
917 
918 /*
919  * Called when a breakpoint was encountered.
920  */
921     void
922 dbg_breakpoint(char_u *name, linenr_T lnum)
923 {
924     /* We need to check if this line is actually executed in do_one_cmd() */
925     debug_breakpoint_name = name;
926     debug_breakpoint_lnum = lnum;
927 }
928 
929 
930 # if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO)
931 /*
932  * Store the current time in "tm".
933  */
934     void
935 profile_start(proftime_T *tm)
936 {
937 # ifdef WIN3264
938     QueryPerformanceCounter(tm);
939 # else
940     gettimeofday(tm, NULL);
941 # endif
942 }
943 
944 /*
945  * Compute the elapsed time from "tm" till now and store in "tm".
946  */
947     void
948 profile_end(proftime_T *tm)
949 {
950     proftime_T now;
951 
952 # ifdef WIN3264
953     QueryPerformanceCounter(&now);
954     tm->QuadPart = now.QuadPart - tm->QuadPart;
955 # else
956     gettimeofday(&now, NULL);
957     tm->tv_usec = now.tv_usec - tm->tv_usec;
958     tm->tv_sec = now.tv_sec - tm->tv_sec;
959     if (tm->tv_usec < 0)
960     {
961 	tm->tv_usec += 1000000;
962 	--tm->tv_sec;
963     }
964 # endif
965 }
966 
967 /*
968  * Subtract the time "tm2" from "tm".
969  */
970     void
971 profile_sub(proftime_T *tm, proftime_T *tm2)
972 {
973 # ifdef WIN3264
974     tm->QuadPart -= tm2->QuadPart;
975 # else
976     tm->tv_usec -= tm2->tv_usec;
977     tm->tv_sec -= tm2->tv_sec;
978     if (tm->tv_usec < 0)
979     {
980 	tm->tv_usec += 1000000;
981 	--tm->tv_sec;
982     }
983 # endif
984 }
985 
986 /*
987  * Return a string that represents the time in "tm".
988  * Uses a static buffer!
989  */
990     char *
991 profile_msg(proftime_T *tm)
992 {
993     static char buf[50];
994 
995 # ifdef WIN3264
996     LARGE_INTEGER   fr;
997 
998     QueryPerformanceFrequency(&fr);
999     sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart);
1000 # else
1001     sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec);
1002 # endif
1003     return buf;
1004 }
1005 
1006 # if defined(FEAT_FLOAT) || defined(PROTO)
1007 /*
1008  * Return a float that represents the time in "tm".
1009  */
1010     float_T
1011 profile_float(proftime_T *tm)
1012 {
1013 #  ifdef WIN3264
1014     LARGE_INTEGER   fr;
1015 
1016     QueryPerformanceFrequency(&fr);
1017     return (float_T)tm->QuadPart / (float_T)fr.QuadPart;
1018 #  else
1019     return (float_T)tm->tv_sec + (float_T)tm->tv_usec / 1000000.0;
1020 #  endif
1021 }
1022 # endif
1023 
1024 /*
1025  * Put the time "msec" past now in "tm".
1026  */
1027     void
1028 profile_setlimit(long msec, proftime_T *tm)
1029 {
1030     if (msec <= 0)   /* no limit */
1031 	profile_zero(tm);
1032     else
1033     {
1034 # ifdef WIN3264
1035 	LARGE_INTEGER   fr;
1036 
1037 	QueryPerformanceCounter(tm);
1038 	QueryPerformanceFrequency(&fr);
1039 	tm->QuadPart += (LONGLONG)((double)msec / 1000.0 * (double)fr.QuadPart);
1040 # else
1041 	long	    usec;
1042 
1043 	gettimeofday(tm, NULL);
1044 	usec = (long)tm->tv_usec + (long)msec * 1000;
1045 	tm->tv_usec = usec % 1000000L;
1046 	tm->tv_sec += usec / 1000000L;
1047 # endif
1048     }
1049 }
1050 
1051 /*
1052  * Return TRUE if the current time is past "tm".
1053  */
1054     int
1055 profile_passed_limit(proftime_T *tm)
1056 {
1057     proftime_T	now;
1058 
1059 # ifdef WIN3264
1060     if (tm->QuadPart == 0)  /* timer was not set */
1061 	return FALSE;
1062     QueryPerformanceCounter(&now);
1063     return (now.QuadPart > tm->QuadPart);
1064 # else
1065     if (tm->tv_sec == 0)    /* timer was not set */
1066 	return FALSE;
1067     gettimeofday(&now, NULL);
1068     return (now.tv_sec > tm->tv_sec
1069 	    || (now.tv_sec == tm->tv_sec && now.tv_usec > tm->tv_usec));
1070 # endif
1071 }
1072 
1073 /*
1074  * Set the time in "tm" to zero.
1075  */
1076     void
1077 profile_zero(proftime_T *tm)
1078 {
1079 # ifdef WIN3264
1080     tm->QuadPart = 0;
1081 # else
1082     tm->tv_usec = 0;
1083     tm->tv_sec = 0;
1084 # endif
1085 }
1086 
1087 # endif  /* FEAT_PROFILE || FEAT_RELTIME */
1088 
1089 # if defined(FEAT_TIMERS) || defined(PROTO)
1090 static timer_T	*first_timer = NULL;
1091 static long	last_timer_id = 0;
1092 
1093 # ifdef WIN3264
1094 #  define GET_TIMEDIFF(timer, now) \
1095 	(long)(((double)(timer->tr_due.QuadPart - now.QuadPart) \
1096 					   / (double)fr.QuadPart) * 1000)
1097 # else
1098 #  define GET_TIMEDIFF(timer, now) \
1099 	(timer->tr_due.tv_sec - now.tv_sec) * 1000 \
1100 			   + (timer->tr_due.tv_usec - now.tv_usec) / 1000
1101 # endif
1102 
1103 /*
1104  * Insert a timer in the list of timers.
1105  */
1106     static void
1107 insert_timer(timer_T *timer)
1108 {
1109     timer->tr_next = first_timer;
1110     timer->tr_prev = NULL;
1111     if (first_timer != NULL)
1112 	first_timer->tr_prev = timer;
1113     first_timer = timer;
1114     did_add_timer = TRUE;
1115 }
1116 
1117 /*
1118  * Take a timer out of the list of timers.
1119  */
1120     static void
1121 remove_timer(timer_T *timer)
1122 {
1123     if (timer->tr_prev == NULL)
1124 	first_timer = timer->tr_next;
1125     else
1126 	timer->tr_prev->tr_next = timer->tr_next;
1127     if (timer->tr_next != NULL)
1128 	timer->tr_next->tr_prev = timer->tr_prev;
1129 }
1130 
1131     static void
1132 free_timer(timer_T *timer)
1133 {
1134     free_callback(timer->tr_callback, timer->tr_partial);
1135     vim_free(timer);
1136 }
1137 
1138 /*
1139  * Create a timer and return it.  NULL if out of memory.
1140  * Caller should set the callback.
1141  */
1142     timer_T *
1143 create_timer(long msec, int repeat)
1144 {
1145     timer_T	*timer = (timer_T *)alloc_clear(sizeof(timer_T));
1146     long	prev_id = last_timer_id;
1147 
1148     if (timer == NULL)
1149 	return NULL;
1150     if (++last_timer_id <= prev_id)
1151 	/* Overflow!  Might cause duplicates... */
1152 	last_timer_id = 0;
1153     timer->tr_id = last_timer_id;
1154     insert_timer(timer);
1155     if (repeat != 0)
1156 	timer->tr_repeat = repeat - 1;
1157     timer->tr_interval = msec;
1158 
1159     profile_setlimit(msec, &timer->tr_due);
1160     return timer;
1161 }
1162 
1163 /*
1164  * Invoke the callback of "timer".
1165  */
1166     static void
1167 timer_callback(timer_T *timer)
1168 {
1169     typval_T	rettv;
1170     int		dummy;
1171     typval_T	argv[2];
1172 
1173     argv[0].v_type = VAR_NUMBER;
1174     argv[0].vval.v_number = (varnumber_T)timer->tr_id;
1175     argv[1].v_type = VAR_UNKNOWN;
1176 
1177     call_func(timer->tr_callback, (int)STRLEN(timer->tr_callback),
1178 			&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE,
1179 			timer->tr_partial, NULL);
1180     clear_tv(&rettv);
1181 }
1182 
1183 /*
1184  * Call timers that are due.
1185  * Return the time in msec until the next timer is due.
1186  * Returns -1 if there are no pending timers.
1187  */
1188     long
1189 check_due_timer(void)
1190 {
1191     timer_T	*timer;
1192     timer_T	*timer_next;
1193     long	this_due;
1194     long	next_due = -1;
1195     proftime_T	now;
1196     int		did_one = FALSE;
1197     long	current_id = last_timer_id;
1198 # ifdef WIN3264
1199     LARGE_INTEGER   fr;
1200 # endif
1201 
1202     /* Don't run any timers while exiting or dealing with an error. */
1203     if (exiting || aborting())
1204 	return next_due;
1205 
1206 # ifdef WIN3264
1207     QueryPerformanceFrequency(&fr);
1208 # endif
1209     profile_start(&now);
1210     for (timer = first_timer; timer != NULL && !got_int; timer = timer_next)
1211     {
1212 	timer_next = timer->tr_next;
1213 
1214 	if (timer->tr_id == -1 || timer->tr_firing || timer->tr_paused)
1215 	    continue;
1216 	this_due = GET_TIMEDIFF(timer, now);
1217 	if (this_due <= 1)
1218 	{
1219 	    int save_timer_busy = timer_busy;
1220 	    int save_vgetc_busy = vgetc_busy;
1221 	    int did_emsg_save = did_emsg;
1222 	    int called_emsg_save = called_emsg;
1223 	    int did_throw_save = did_throw;
1224 
1225 	    timer_busy = timer_busy > 0 || vgetc_busy > 0;
1226 	    vgetc_busy = 0;
1227 	    called_emsg = FALSE;
1228 	    timer->tr_firing = TRUE;
1229 	    timer_callback(timer);
1230 	    timer->tr_firing = FALSE;
1231 	    timer_next = timer->tr_next;
1232 	    did_one = TRUE;
1233 	    timer_busy = save_timer_busy;
1234 	    vgetc_busy = save_vgetc_busy;
1235 	    if (called_emsg)
1236 	    {
1237 		++timer->tr_emsg_count;
1238 		if (!did_throw_save && did_throw && current_exception != NULL)
1239 		    discard_current_exception();
1240 	    }
1241 	    did_emsg = did_emsg_save;
1242 	    called_emsg = called_emsg_save;
1243 
1244 	    /* Only fire the timer again if it repeats and stop_timer() wasn't
1245 	     * called while inside the callback (tr_id == -1). */
1246 	    if (timer->tr_repeat != 0 && timer->tr_id != -1
1247 		    && timer->tr_emsg_count < 3)
1248 	    {
1249 		profile_setlimit(timer->tr_interval, &timer->tr_due);
1250 		this_due = GET_TIMEDIFF(timer, now);
1251 		if (this_due < 1)
1252 		    this_due = 1;
1253 		if (timer->tr_repeat > 0)
1254 		    --timer->tr_repeat;
1255 	    }
1256 	    else
1257 	    {
1258 		this_due = -1;
1259 		remove_timer(timer);
1260 		free_timer(timer);
1261 	    }
1262 	}
1263 	if (this_due > 0 && (next_due == -1 || next_due > this_due))
1264 	    next_due = this_due;
1265     }
1266 
1267     if (did_one)
1268 	redraw_after_callback();
1269 
1270     return current_id != last_timer_id ? 1 : next_due;
1271 }
1272 
1273 /*
1274  * Find a timer by ID.  Returns NULL if not found;
1275  */
1276     timer_T *
1277 find_timer(long id)
1278 {
1279     timer_T *timer;
1280 
1281     if (id >= 0)
1282     {
1283 	for (timer = first_timer; timer != NULL; timer = timer->tr_next)
1284 	    if (timer->tr_id == id)
1285 		return timer;
1286     }
1287     return NULL;
1288 }
1289 
1290 
1291 /*
1292  * Stop a timer and delete it.
1293  */
1294     void
1295 stop_timer(timer_T *timer)
1296 {
1297     if (timer->tr_firing)
1298 	/* Free the timer after the callback returns. */
1299 	timer->tr_id = -1;
1300     else
1301     {
1302 	remove_timer(timer);
1303 	free_timer(timer);
1304     }
1305 }
1306 
1307     void
1308 stop_all_timers(void)
1309 {
1310     timer_T *timer;
1311     timer_T *timer_next;
1312 
1313     for (timer = first_timer; timer != NULL; timer = timer_next)
1314     {
1315 	timer_next = timer->tr_next;
1316 	stop_timer(timer);
1317     }
1318 }
1319 
1320     void
1321 add_timer_info(typval_T *rettv, timer_T *timer)
1322 {
1323     list_T	*list = rettv->vval.v_list;
1324     dict_T	*dict = dict_alloc();
1325     dictitem_T	*di;
1326     long	remaining;
1327     proftime_T	now;
1328 # ifdef WIN3264
1329     LARGE_INTEGER   fr;
1330 #endif
1331 
1332     if (dict == NULL)
1333 	return;
1334     list_append_dict(list, dict);
1335 
1336     dict_add_nr_str(dict, "id", timer->tr_id, NULL);
1337     dict_add_nr_str(dict, "time", (long)timer->tr_interval, NULL);
1338 
1339     profile_start(&now);
1340 # ifdef WIN3264
1341     QueryPerformanceFrequency(&fr);
1342 # endif
1343     remaining = GET_TIMEDIFF(timer, now);
1344     dict_add_nr_str(dict, "remaining", (long)remaining, NULL);
1345 
1346     dict_add_nr_str(dict, "repeat",
1347 	       (long)(timer->tr_repeat < 0 ? -1 : timer->tr_repeat + 1), NULL);
1348     dict_add_nr_str(dict, "paused", (long)(timer->tr_paused), NULL);
1349 
1350     di = dictitem_alloc((char_u *)"callback");
1351     if (di != NULL)
1352     {
1353 	if (dict_add(dict, di) == FAIL)
1354 	    vim_free(di);
1355 	else if (timer->tr_partial != NULL)
1356 	{
1357 	    di->di_tv.v_type = VAR_PARTIAL;
1358 	    di->di_tv.vval.v_partial = timer->tr_partial;
1359 	    ++timer->tr_partial->pt_refcount;
1360 	}
1361 	else
1362 	{
1363 	    di->di_tv.v_type = VAR_FUNC;
1364 	    di->di_tv.vval.v_string = vim_strsave(timer->tr_callback);
1365 	}
1366 	di->di_tv.v_lock = 0;
1367     }
1368 }
1369 
1370     void
1371 add_timer_info_all(typval_T *rettv)
1372 {
1373     timer_T *timer;
1374 
1375     for (timer = first_timer; timer != NULL; timer = timer->tr_next)
1376 	if (timer->tr_id != -1)
1377 	    add_timer_info(rettv, timer);
1378 }
1379 
1380 /*
1381  * Mark references in partials of timers.
1382  */
1383     int
1384 set_ref_in_timer(int copyID)
1385 {
1386     int		abort = FALSE;
1387     timer_T	*timer;
1388     typval_T	tv;
1389 
1390     for (timer = first_timer; timer != NULL; timer = timer->tr_next)
1391     {
1392 	if (timer->tr_partial != NULL)
1393 	{
1394 	    tv.v_type = VAR_PARTIAL;
1395 	    tv.vval.v_partial = timer->tr_partial;
1396 	}
1397 	else
1398 	{
1399 	    tv.v_type = VAR_FUNC;
1400 	    tv.vval.v_string = timer->tr_callback;
1401 	}
1402 	abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL);
1403     }
1404     return abort;
1405 }
1406 
1407 #  if defined(EXITFREE) || defined(PROTO)
1408     void
1409 timer_free_all()
1410 {
1411     timer_T *timer;
1412 
1413     while (first_timer != NULL)
1414     {
1415 	timer = first_timer;
1416 	remove_timer(timer);
1417 	free_timer(timer);
1418     }
1419 }
1420 #  endif
1421 # endif
1422 
1423 #if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) && defined(FEAT_FLOAT)
1424 # if defined(HAVE_MATH_H)
1425 #  include <math.h>
1426 # endif
1427 
1428 /*
1429  * Divide the time "tm" by "count" and store in "tm2".
1430  */
1431     void
1432 profile_divide(proftime_T *tm, int count, proftime_T *tm2)
1433 {
1434     if (count == 0)
1435 	profile_zero(tm2);
1436     else
1437     {
1438 # ifdef WIN3264
1439 	tm2->QuadPart = tm->QuadPart / count;
1440 # else
1441 	double usec = (tm->tv_sec * 1000000.0 + tm->tv_usec) / count;
1442 
1443 	tm2->tv_sec = floor(usec / 1000000.0);
1444 	tm2->tv_usec = vim_round(usec - (tm2->tv_sec * 1000000.0));
1445 # endif
1446     }
1447 }
1448 #endif
1449 
1450 # if defined(FEAT_PROFILE) || defined(PROTO)
1451 /*
1452  * Functions for profiling.
1453  */
1454 static void script_do_profile(scriptitem_T *si);
1455 static void script_dump_profile(FILE *fd);
1456 static proftime_T prof_wait_time;
1457 
1458 /*
1459  * Add the time "tm2" to "tm".
1460  */
1461     void
1462 profile_add(proftime_T *tm, proftime_T *tm2)
1463 {
1464 # ifdef WIN3264
1465     tm->QuadPart += tm2->QuadPart;
1466 # else
1467     tm->tv_usec += tm2->tv_usec;
1468     tm->tv_sec += tm2->tv_sec;
1469     if (tm->tv_usec >= 1000000)
1470     {
1471 	tm->tv_usec -= 1000000;
1472 	++tm->tv_sec;
1473     }
1474 # endif
1475 }
1476 
1477 /*
1478  * Add the "self" time from the total time and the children's time.
1479  */
1480     void
1481 profile_self(proftime_T *self, proftime_T *total, proftime_T *children)
1482 {
1483     /* Check that the result won't be negative.  Can happen with recursive
1484      * calls. */
1485 #ifdef WIN3264
1486     if (total->QuadPart <= children->QuadPart)
1487 	return;
1488 #else
1489     if (total->tv_sec < children->tv_sec
1490 	    || (total->tv_sec == children->tv_sec
1491 		&& total->tv_usec <= children->tv_usec))
1492 	return;
1493 #endif
1494     profile_add(self, total);
1495     profile_sub(self, children);
1496 }
1497 
1498 /*
1499  * Get the current waittime.
1500  */
1501     void
1502 profile_get_wait(proftime_T *tm)
1503 {
1504     *tm = prof_wait_time;
1505 }
1506 
1507 /*
1508  * Subtract the passed waittime since "tm" from "tma".
1509  */
1510     void
1511 profile_sub_wait(proftime_T *tm, proftime_T *tma)
1512 {
1513     proftime_T tm3 = prof_wait_time;
1514 
1515     profile_sub(&tm3, tm);
1516     profile_sub(tma, &tm3);
1517 }
1518 
1519 /*
1520  * Return TRUE if "tm1" and "tm2" are equal.
1521  */
1522     int
1523 profile_equal(proftime_T *tm1, proftime_T *tm2)
1524 {
1525 # ifdef WIN3264
1526     return (tm1->QuadPart == tm2->QuadPart);
1527 # else
1528     return (tm1->tv_usec == tm2->tv_usec && tm1->tv_sec == tm2->tv_sec);
1529 # endif
1530 }
1531 
1532 /*
1533  * Return <0, 0 or >0 if "tm1" < "tm2", "tm1" == "tm2" or "tm1" > "tm2"
1534  */
1535     int
1536 profile_cmp(const proftime_T *tm1, const proftime_T *tm2)
1537 {
1538 # ifdef WIN3264
1539     return (int)(tm2->QuadPart - tm1->QuadPart);
1540 # else
1541     if (tm1->tv_sec == tm2->tv_sec)
1542 	return tm2->tv_usec - tm1->tv_usec;
1543     return tm2->tv_sec - tm1->tv_sec;
1544 # endif
1545 }
1546 
1547 static char_u	*profile_fname = NULL;
1548 static proftime_T pause_time;
1549 
1550 /*
1551  * ":profile cmd args"
1552  */
1553     void
1554 ex_profile(exarg_T *eap)
1555 {
1556     char_u	*e;
1557     int		len;
1558 
1559     e = skiptowhite(eap->arg);
1560     len = (int)(e - eap->arg);
1561     e = skipwhite(e);
1562 
1563     if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL)
1564     {
1565 	vim_free(profile_fname);
1566 	profile_fname = expand_env_save_opt(e, TRUE);
1567 	do_profiling = PROF_YES;
1568 	profile_zero(&prof_wait_time);
1569 	set_vim_var_nr(VV_PROFILING, 1L);
1570     }
1571     else if (do_profiling == PROF_NONE)
1572 	EMSG(_("E750: First use \":profile start {fname}\""));
1573     else if (STRCMP(eap->arg, "pause") == 0)
1574     {
1575 	if (do_profiling == PROF_YES)
1576 	    profile_start(&pause_time);
1577 	do_profiling = PROF_PAUSED;
1578     }
1579     else if (STRCMP(eap->arg, "continue") == 0)
1580     {
1581 	if (do_profiling == PROF_PAUSED)
1582 	{
1583 	    profile_end(&pause_time);
1584 	    profile_add(&prof_wait_time, &pause_time);
1585 	}
1586 	do_profiling = PROF_YES;
1587     }
1588     else
1589     {
1590 	/* The rest is similar to ":breakadd". */
1591 	ex_breakadd(eap);
1592     }
1593 }
1594 
1595 /* Command line expansion for :profile. */
1596 static enum
1597 {
1598     PEXP_SUBCMD,	/* expand :profile sub-commands */
1599     PEXP_FUNC		/* expand :profile func {funcname} */
1600 } pexpand_what;
1601 
1602 static char *pexpand_cmds[] = {
1603 			"start",
1604 #define PROFCMD_START	0
1605 			"pause",
1606 #define PROFCMD_PAUSE	1
1607 			"continue",
1608 #define PROFCMD_CONTINUE 2
1609 			"func",
1610 #define PROFCMD_FUNC	3
1611 			"file",
1612 #define PROFCMD_FILE	4
1613 			NULL
1614 #define PROFCMD_LAST	5
1615 };
1616 
1617 /*
1618  * Function given to ExpandGeneric() to obtain the profile command
1619  * specific expansion.
1620  */
1621     char_u *
1622 get_profile_name(expand_T *xp UNUSED, int idx)
1623 {
1624     switch (pexpand_what)
1625     {
1626     case PEXP_SUBCMD:
1627 	return (char_u *)pexpand_cmds[idx];
1628     /* case PEXP_FUNC: TODO */
1629     default:
1630 	return NULL;
1631     }
1632 }
1633 
1634 /*
1635  * Handle command line completion for :profile command.
1636  */
1637     void
1638 set_context_in_profile_cmd(expand_T *xp, char_u *arg)
1639 {
1640     char_u	*end_subcmd;
1641 
1642     /* Default: expand subcommands. */
1643     xp->xp_context = EXPAND_PROFILE;
1644     pexpand_what = PEXP_SUBCMD;
1645     xp->xp_pattern = arg;
1646 
1647     end_subcmd = skiptowhite(arg);
1648     if (*end_subcmd == NUL)
1649 	return;
1650 
1651     if (end_subcmd - arg == 5 && STRNCMP(arg, "start", 5) == 0)
1652     {
1653 	xp->xp_context = EXPAND_FILES;
1654 	xp->xp_pattern = skipwhite(end_subcmd);
1655 	return;
1656     }
1657 
1658     /* TODO: expand function names after "func" */
1659     xp->xp_context = EXPAND_NOTHING;
1660 }
1661 
1662 /*
1663  * Dump the profiling info.
1664  */
1665     void
1666 profile_dump(void)
1667 {
1668     FILE	*fd;
1669 
1670     if (profile_fname != NULL)
1671     {
1672 	fd = mch_fopen((char *)profile_fname, "w");
1673 	if (fd == NULL)
1674 	    EMSG2(_(e_notopen), profile_fname);
1675 	else
1676 	{
1677 	    script_dump_profile(fd);
1678 	    func_dump_profile(fd);
1679 	    fclose(fd);
1680 	}
1681     }
1682 }
1683 
1684 /*
1685  * Start profiling script "fp".
1686  */
1687     static void
1688 script_do_profile(scriptitem_T *si)
1689 {
1690     si->sn_pr_count = 0;
1691     profile_zero(&si->sn_pr_total);
1692     profile_zero(&si->sn_pr_self);
1693 
1694     ga_init2(&si->sn_prl_ga, sizeof(sn_prl_T), 100);
1695     si->sn_prl_idx = -1;
1696     si->sn_prof_on = TRUE;
1697     si->sn_pr_nest = 0;
1698 }
1699 
1700 /*
1701  * save time when starting to invoke another script or function.
1702  */
1703     void
1704 script_prof_save(
1705     proftime_T	*tm)	    /* place to store wait time */
1706 {
1707     scriptitem_T    *si;
1708 
1709     if (current_SID > 0 && current_SID <= script_items.ga_len)
1710     {
1711 	si = &SCRIPT_ITEM(current_SID);
1712 	if (si->sn_prof_on && si->sn_pr_nest++ == 0)
1713 	    profile_start(&si->sn_pr_child);
1714     }
1715     profile_get_wait(tm);
1716 }
1717 
1718 /*
1719  * Count time spent in children after invoking another script or function.
1720  */
1721     void
1722 script_prof_restore(proftime_T *tm)
1723 {
1724     scriptitem_T    *si;
1725 
1726     if (current_SID > 0 && current_SID <= script_items.ga_len)
1727     {
1728 	si = &SCRIPT_ITEM(current_SID);
1729 	if (si->sn_prof_on && --si->sn_pr_nest == 0)
1730 	{
1731 	    profile_end(&si->sn_pr_child);
1732 	    profile_sub_wait(tm, &si->sn_pr_child); /* don't count wait time */
1733 	    profile_add(&si->sn_pr_children, &si->sn_pr_child);
1734 	    profile_add(&si->sn_prl_children, &si->sn_pr_child);
1735 	}
1736     }
1737 }
1738 
1739 static proftime_T inchar_time;
1740 
1741 /*
1742  * Called when starting to wait for the user to type a character.
1743  */
1744     void
1745 prof_inchar_enter(void)
1746 {
1747     profile_start(&inchar_time);
1748 }
1749 
1750 /*
1751  * Called when finished waiting for the user to type a character.
1752  */
1753     void
1754 prof_inchar_exit(void)
1755 {
1756     profile_end(&inchar_time);
1757     profile_add(&prof_wait_time, &inchar_time);
1758 }
1759 
1760 /*
1761  * Dump the profiling results for all scripts in file "fd".
1762  */
1763     static void
1764 script_dump_profile(FILE *fd)
1765 {
1766     int		    id;
1767     scriptitem_T    *si;
1768     int		    i;
1769     FILE	    *sfd;
1770     sn_prl_T	    *pp;
1771 
1772     for (id = 1; id <= script_items.ga_len; ++id)
1773     {
1774 	si = &SCRIPT_ITEM(id);
1775 	if (si->sn_prof_on)
1776 	{
1777 	    fprintf(fd, "SCRIPT  %s\n", si->sn_name);
1778 	    if (si->sn_pr_count == 1)
1779 		fprintf(fd, "Sourced 1 time\n");
1780 	    else
1781 		fprintf(fd, "Sourced %d times\n", si->sn_pr_count);
1782 	    fprintf(fd, "Total time: %s\n", profile_msg(&si->sn_pr_total));
1783 	    fprintf(fd, " Self time: %s\n", profile_msg(&si->sn_pr_self));
1784 	    fprintf(fd, "\n");
1785 	    fprintf(fd, "count  total (s)   self (s)\n");
1786 
1787 	    sfd = mch_fopen((char *)si->sn_name, "r");
1788 	    if (sfd == NULL)
1789 		fprintf(fd, "Cannot open file!\n");
1790 	    else
1791 	    {
1792 		for (i = 0; i < si->sn_prl_ga.ga_len; ++i)
1793 		{
1794 		    if (vim_fgets(IObuff, IOSIZE, sfd))
1795 			break;
1796 		    pp = &PRL_ITEM(si, i);
1797 		    if (pp->snp_count > 0)
1798 		    {
1799 			fprintf(fd, "%5d ", pp->snp_count);
1800 			if (profile_equal(&pp->sn_prl_total, &pp->sn_prl_self))
1801 			    fprintf(fd, "           ");
1802 			else
1803 			    fprintf(fd, "%s ", profile_msg(&pp->sn_prl_total));
1804 			fprintf(fd, "%s ", profile_msg(&pp->sn_prl_self));
1805 		    }
1806 		    else
1807 			fprintf(fd, "                            ");
1808 		    fprintf(fd, "%s", IObuff);
1809 		}
1810 		fclose(sfd);
1811 	    }
1812 	    fprintf(fd, "\n");
1813 	}
1814     }
1815 }
1816 
1817 /*
1818  * Return TRUE when a function defined in the current script should be
1819  * profiled.
1820  */
1821     int
1822 prof_def_func(void)
1823 {
1824     if (current_SID > 0)
1825 	return SCRIPT_ITEM(current_SID).sn_pr_force;
1826     return FALSE;
1827 }
1828 
1829 # endif
1830 #endif
1831 
1832 /*
1833  * If 'autowrite' option set, try to write the file.
1834  * Careful: autocommands may make "buf" invalid!
1835  *
1836  * return FAIL for failure, OK otherwise
1837  */
1838     int
1839 autowrite(buf_T *buf, int forceit)
1840 {
1841     int		r;
1842     bufref_T	bufref;
1843 
1844     if (!(p_aw || p_awa) || !p_write
1845 #ifdef FEAT_QUICKFIX
1846 	    /* never autowrite a "nofile" or "nowrite" buffer */
1847 	    || bt_dontwrite(buf)
1848 #endif
1849 	    || (!forceit && buf->b_p_ro) || buf->b_ffname == NULL)
1850 	return FAIL;
1851     set_bufref(&bufref, buf);
1852     r = buf_write_all(buf, forceit);
1853 
1854     /* Writing may succeed but the buffer still changed, e.g., when there is a
1855      * conversion error.  We do want to return FAIL then. */
1856     if (bufref_valid(&bufref) && bufIsChanged(buf))
1857 	r = FAIL;
1858     return r;
1859 }
1860 
1861 /*
1862  * flush all buffers, except the ones that are readonly
1863  */
1864     void
1865 autowrite_all(void)
1866 {
1867     buf_T	*buf;
1868 
1869     if (!(p_aw || p_awa) || !p_write)
1870 	return;
1871     FOR_ALL_BUFFERS(buf)
1872 	if (bufIsChanged(buf) && !buf->b_p_ro)
1873 	{
1874 #ifdef FEAT_AUTOCMD
1875 	    bufref_T	bufref;
1876 
1877 	    set_bufref(&bufref, buf);
1878 #endif
1879 	    (void)buf_write_all(buf, FALSE);
1880 #ifdef FEAT_AUTOCMD
1881 	    /* an autocommand may have deleted the buffer */
1882 	    if (!bufref_valid(&bufref))
1883 		buf = firstbuf;
1884 #endif
1885 	}
1886 }
1887 
1888 /*
1889  * Return TRUE if buffer was changed and cannot be abandoned.
1890  * For flags use the CCGD_ values.
1891  */
1892     int
1893 check_changed(buf_T *buf, int flags)
1894 {
1895     int		forceit = (flags & CCGD_FORCEIT);
1896 #ifdef FEAT_AUTOCMD
1897     bufref_T	bufref;
1898 
1899     set_bufref(&bufref, buf);
1900 #endif
1901 
1902     if (       !forceit
1903 	    && bufIsChanged(buf)
1904 	    && ((flags & CCGD_MULTWIN) || buf->b_nwindows <= 1)
1905 	    && (!(flags & CCGD_AW) || autowrite(buf, forceit) == FAIL))
1906     {
1907 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1908 	if ((p_confirm || cmdmod.confirm) && p_write)
1909 	{
1910 	    buf_T	*buf2;
1911 	    int		count = 0;
1912 
1913 	    if (flags & CCGD_ALLBUF)
1914 		FOR_ALL_BUFFERS(buf2)
1915 		    if (bufIsChanged(buf2)
1916 				     && (buf2->b_ffname != NULL
1917 # ifdef FEAT_BROWSE
1918 					 || cmdmod.browse
1919 # endif
1920 					))
1921 			++count;
1922 # ifdef FEAT_AUTOCMD
1923 	    if (!bufref_valid(&bufref))
1924 		/* Autocommand deleted buffer, oops!  It's not changed now. */
1925 		return FALSE;
1926 # endif
1927 	    dialog_changed(buf, count > 1);
1928 # ifdef FEAT_AUTOCMD
1929 	    if (!bufref_valid(&bufref))
1930 		/* Autocommand deleted buffer, oops!  It's not changed now. */
1931 		return FALSE;
1932 # endif
1933 	    return bufIsChanged(buf);
1934 	}
1935 #endif
1936 	if (flags & CCGD_EXCMD)
1937 	    EMSG(_(e_nowrtmsg));
1938 	else
1939 	    EMSG(_(e_nowrtmsg_nobang));
1940 	return TRUE;
1941     }
1942     return FALSE;
1943 }
1944 
1945 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO)
1946 
1947 #if defined(FEAT_BROWSE) || defined(PROTO)
1948 /*
1949  * When wanting to write a file without a file name, ask the user for a name.
1950  */
1951     void
1952 browse_save_fname(buf_T *buf)
1953 {
1954     if (buf->b_fname == NULL)
1955     {
1956 	char_u *fname;
1957 
1958 	fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"),
1959 						 NULL, NULL, NULL, NULL, buf);
1960 	if (fname != NULL)
1961 	{
1962 	    if (setfname(buf, fname, NULL, TRUE) == OK)
1963 		buf->b_flags |= BF_NOTEDITED;
1964 	    vim_free(fname);
1965 	}
1966     }
1967 }
1968 #endif
1969 
1970 /*
1971  * Ask the user what to do when abandoning a changed buffer.
1972  * Must check 'write' option first!
1973  */
1974     void
1975 dialog_changed(
1976     buf_T	*buf,
1977     int		checkall)	/* may abandon all changed buffers */
1978 {
1979     char_u	buff[DIALOG_MSG_SIZE];
1980     int		ret;
1981     buf_T	*buf2;
1982     exarg_T     ea;
1983 
1984     dialog_msg(buff, _("Save changes to \"%s\"?"),
1985 			(buf->b_fname != NULL) ?
1986 			buf->b_fname : (char_u *)_("Untitled"));
1987     if (checkall)
1988 	ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
1989     else
1990 	ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
1991 
1992     /* Init ea pseudo-structure, this is needed for the check_overwrite()
1993      * function. */
1994     ea.append = ea.forceit = FALSE;
1995 
1996     if (ret == VIM_YES)
1997     {
1998 #ifdef FEAT_BROWSE
1999 	/* May get file name, when there is none */
2000 	browse_save_fname(buf);
2001 #endif
2002 	if (buf->b_fname != NULL && check_overwrite(&ea, buf,
2003 				    buf->b_fname, buf->b_ffname, FALSE) == OK)
2004 	    /* didn't hit Cancel */
2005 	    (void)buf_write_all(buf, FALSE);
2006     }
2007     else if (ret == VIM_NO)
2008     {
2009 	unchanged(buf, TRUE);
2010     }
2011     else if (ret == VIM_ALL)
2012     {
2013 	/*
2014 	 * Write all modified files that can be written.
2015 	 * Skip readonly buffers, these need to be confirmed
2016 	 * individually.
2017 	 */
2018 	FOR_ALL_BUFFERS(buf2)
2019 	{
2020 	    if (bufIsChanged(buf2)
2021 		    && (buf2->b_ffname != NULL
2022 #ifdef FEAT_BROWSE
2023 			|| cmdmod.browse
2024 #endif
2025 			)
2026 		    && !buf2->b_p_ro)
2027 	    {
2028 #ifdef FEAT_AUTOCMD
2029 		bufref_T bufref;
2030 
2031 		set_bufref(&bufref, buf2);
2032 #endif
2033 #ifdef FEAT_BROWSE
2034 		/* May get file name, when there is none */
2035 		browse_save_fname(buf2);
2036 #endif
2037 		if (buf2->b_fname != NULL && check_overwrite(&ea, buf2,
2038 				  buf2->b_fname, buf2->b_ffname, FALSE) == OK)
2039 		    /* didn't hit Cancel */
2040 		    (void)buf_write_all(buf2, FALSE);
2041 #ifdef FEAT_AUTOCMD
2042 		/* an autocommand may have deleted the buffer */
2043 		if (!bufref_valid(&bufref))
2044 		    buf2 = firstbuf;
2045 #endif
2046 	    }
2047 	}
2048     }
2049     else if (ret == VIM_DISCARDALL)
2050     {
2051 	/*
2052 	 * mark all buffers as unchanged
2053 	 */
2054 	FOR_ALL_BUFFERS(buf2)
2055 	    unchanged(buf2, TRUE);
2056     }
2057 }
2058 #endif
2059 
2060 /*
2061  * Return TRUE if the buffer "buf" can be abandoned, either by making it
2062  * hidden, autowriting it or unloading it.
2063  */
2064     int
2065 can_abandon(buf_T *buf, int forceit)
2066 {
2067     return (	   buf_hide(buf)
2068 		|| !bufIsChanged(buf)
2069 		|| buf->b_nwindows > 1
2070 		|| autowrite(buf, forceit) == OK
2071 		|| forceit);
2072 }
2073 
2074 static void add_bufnum(int *bufnrs, int *bufnump, int nr);
2075 
2076 /*
2077  * Add a buffer number to "bufnrs", unless it's already there.
2078  */
2079     static void
2080 add_bufnum(int *bufnrs, int *bufnump, int nr)
2081 {
2082     int i;
2083 
2084     for (i = 0; i < *bufnump; ++i)
2085 	if (bufnrs[i] == nr)
2086 	    return;
2087     bufnrs[*bufnump] = nr;
2088     *bufnump = *bufnump + 1;
2089 }
2090 
2091 /*
2092  * Return TRUE if any buffer was changed and cannot be abandoned.
2093  * That changed buffer becomes the current buffer.
2094  * When "unload" is true the current buffer is unloaded instead of making it
2095  * hidden.  This is used for ":q!".
2096  */
2097     int
2098 check_changed_any(
2099     int		hidden,		/* Only check hidden buffers */
2100     int		unload)
2101 {
2102     int		ret = FALSE;
2103     buf_T	*buf;
2104     int		save;
2105     int		i;
2106     int		bufnum = 0;
2107     int		bufcount = 0;
2108     int		*bufnrs;
2109 #ifdef FEAT_WINDOWS
2110     tabpage_T   *tp;
2111     win_T	*wp;
2112 #endif
2113 
2114     FOR_ALL_BUFFERS(buf)
2115 	++bufcount;
2116 
2117     if (bufcount == 0)
2118 	return FALSE;
2119 
2120     bufnrs = (int *)alloc(sizeof(int) * bufcount);
2121     if (bufnrs == NULL)
2122 	return FALSE;
2123 
2124     /* curbuf */
2125     bufnrs[bufnum++] = curbuf->b_fnum;
2126 #ifdef FEAT_WINDOWS
2127     /* buf in curtab */
2128     FOR_ALL_WINDOWS(wp)
2129 	if (wp->w_buffer != curbuf)
2130 	    add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum);
2131 
2132     /* buf in other tab */
2133     FOR_ALL_TABPAGES(tp)
2134 	if (tp != curtab)
2135 	    for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
2136 		add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum);
2137 #endif
2138     /* any other buf */
2139     FOR_ALL_BUFFERS(buf)
2140 	add_bufnum(bufnrs, &bufnum, buf->b_fnum);
2141 
2142     for (i = 0; i < bufnum; ++i)
2143     {
2144 	buf = buflist_findnr(bufnrs[i]);
2145 	if (buf == NULL)
2146 	    continue;
2147 	if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf))
2148 	{
2149 	    bufref_T bufref;
2150 
2151 	    set_bufref(&bufref, buf);
2152 	    /* Try auto-writing the buffer.  If this fails but the buffer no
2153 	    * longer exists it's not changed, that's OK. */
2154 	    if (check_changed(buf, (p_awa ? CCGD_AW : 0)
2155 				 | CCGD_MULTWIN
2156 				 | CCGD_ALLBUF) && bufref_valid(&bufref))
2157 		break;	    /* didn't save - still changes */
2158 	}
2159     }
2160 
2161     if (i >= bufnum)
2162 	goto theend;
2163 
2164     ret = TRUE;
2165     exiting = FALSE;
2166 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2167     /*
2168      * When ":confirm" used, don't give an error message.
2169      */
2170     if (!(p_confirm || cmdmod.confirm))
2171 #endif
2172     {
2173 	/* There must be a wait_return for this message, do_buffer()
2174 	 * may cause a redraw.  But wait_return() is a no-op when vgetc()
2175 	 * is busy (Quit used from window menu), then make sure we don't
2176 	 * cause a scroll up. */
2177 	if (vgetc_busy > 0)
2178 	{
2179 	    msg_row = cmdline_row;
2180 	    msg_col = 0;
2181 	    msg_didout = FALSE;
2182 	}
2183 	if (
2184 #ifdef FEAT_TERMINAL
2185 		term_job_running(buf->b_term)
2186 		    ? EMSG2(_("E947: Job still running in buffer \"%s\""),
2187 								  buf->b_fname)
2188 		    :
2189 #endif
2190 		EMSG2(_("E162: No write since last change for buffer \"%s\""),
2191 		    buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname))
2192 	{
2193 	    save = no_wait_return;
2194 	    no_wait_return = FALSE;
2195 	    wait_return(FALSE);
2196 	    no_wait_return = save;
2197 	}
2198     }
2199 
2200 #ifdef FEAT_WINDOWS
2201     /* Try to find a window that contains the buffer. */
2202     if (buf != curbuf)
2203 	FOR_ALL_TAB_WINDOWS(tp, wp)
2204 	    if (wp->w_buffer == buf)
2205 	    {
2206 # ifdef FEAT_AUTOCMD
2207 		bufref_T bufref;
2208 
2209 		set_bufref(&bufref, buf);
2210 # endif
2211 		goto_tabpage_win(tp, wp);
2212 # ifdef FEAT_AUTOCMD
2213 		/* Paranoia: did autocms wipe out the buffer with changes? */
2214 		if (!bufref_valid(&bufref))
2215 		{
2216 		    goto theend;
2217 		}
2218 # endif
2219 		goto buf_found;
2220 	    }
2221 buf_found:
2222 #endif
2223 
2224     /* Open the changed buffer in the current window. */
2225     if (buf != curbuf)
2226 	set_curbuf(buf, unload ? DOBUF_UNLOAD : DOBUF_GOTO);
2227 
2228 theend:
2229     vim_free(bufnrs);
2230     return ret;
2231 }
2232 
2233 /*
2234  * return FAIL if there is no file name, OK if there is one
2235  * give error message for FAIL
2236  */
2237     int
2238 check_fname(void)
2239 {
2240     if (curbuf->b_ffname == NULL)
2241     {
2242 	EMSG(_(e_noname));
2243 	return FAIL;
2244     }
2245     return OK;
2246 }
2247 
2248 /*
2249  * flush the contents of a buffer, unless it has no file name
2250  *
2251  * return FAIL for failure, OK otherwise
2252  */
2253     int
2254 buf_write_all(buf_T *buf, int forceit)
2255 {
2256     int	    retval;
2257 #ifdef FEAT_AUTOCMD
2258     buf_T	*old_curbuf = curbuf;
2259 #endif
2260 
2261     retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
2262 				   (linenr_T)1, buf->b_ml.ml_line_count, NULL,
2263 						  FALSE, forceit, TRUE, FALSE));
2264 #ifdef FEAT_AUTOCMD
2265     if (curbuf != old_curbuf)
2266     {
2267 	msg_source(HL_ATTR(HLF_W));
2268 	MSG(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
2269     }
2270 #endif
2271     return retval;
2272 }
2273 
2274 /*
2275  * Code to handle the argument list.
2276  */
2277 
2278 static char_u	*do_one_arg(char_u *str);
2279 static int	do_arglist(char_u *str, int what, int after);
2280 static void	alist_check_arg_idx(void);
2281 static int	editing_arg_idx(win_T *win);
2282 #ifdef FEAT_LISTCMDS
2283 static int	alist_add_list(int count, char_u **files, int after);
2284 #endif
2285 #define AL_SET	1
2286 #define AL_ADD	2
2287 #define AL_DEL	3
2288 
2289 /*
2290  * Isolate one argument, taking backticks.
2291  * Changes the argument in-place, puts a NUL after it.  Backticks remain.
2292  * Return a pointer to the start of the next argument.
2293  */
2294     static char_u *
2295 do_one_arg(char_u *str)
2296 {
2297     char_u	*p;
2298     int		inbacktick;
2299 
2300     inbacktick = FALSE;
2301     for (p = str; *str; ++str)
2302     {
2303 	/* When the backslash is used for escaping the special meaning of a
2304 	 * character we need to keep it until wildcard expansion. */
2305 	if (rem_backslash(str))
2306 	{
2307 	    *p++ = *str++;
2308 	    *p++ = *str;
2309 	}
2310 	else
2311 	{
2312 	    /* An item ends at a space not in backticks */
2313 	    if (!inbacktick && vim_isspace(*str))
2314 		break;
2315 	    if (*str == '`')
2316 		inbacktick ^= TRUE;
2317 	    *p++ = *str;
2318 	}
2319     }
2320     str = skipwhite(str);
2321     *p = NUL;
2322 
2323     return str;
2324 }
2325 
2326 /*
2327  * Separate the arguments in "str" and return a list of pointers in the
2328  * growarray "gap".
2329  */
2330     static int
2331 get_arglist(garray_T *gap, char_u *str, int escaped)
2332 {
2333     ga_init2(gap, (int)sizeof(char_u *), 20);
2334     while (*str != NUL)
2335     {
2336 	if (ga_grow(gap, 1) == FAIL)
2337 	{
2338 	    ga_clear(gap);
2339 	    return FAIL;
2340 	}
2341 	((char_u **)gap->ga_data)[gap->ga_len++] = str;
2342 
2343 	/* If str is escaped, don't handle backslashes or spaces */
2344 	if (!escaped)
2345 	    return OK;
2346 
2347 	/* Isolate one argument, change it in-place, put a NUL after it. */
2348 	str = do_one_arg(str);
2349     }
2350     return OK;
2351 }
2352 
2353 #if defined(FEAT_QUICKFIX) || defined(FEAT_SYN_HL) || defined(PROTO)
2354 /*
2355  * Parse a list of arguments (file names), expand them and return in
2356  * "fnames[fcountp]".  When "wig" is TRUE, removes files matching 'wildignore'.
2357  * Return FAIL or OK.
2358  */
2359     int
2360 get_arglist_exp(
2361     char_u	*str,
2362     int		*fcountp,
2363     char_u	***fnamesp,
2364     int		wig)
2365 {
2366     garray_T	ga;
2367     int		i;
2368 
2369     if (get_arglist(&ga, str, TRUE) == FAIL)
2370 	return FAIL;
2371     if (wig == TRUE)
2372 	i = expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
2373 					fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
2374     else
2375 	i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
2376 					fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
2377 
2378     ga_clear(&ga);
2379     return i;
2380 }
2381 #endif
2382 
2383 #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
2384 /*
2385  * Redefine the argument list.
2386  */
2387     void
2388 set_arglist(char_u *str)
2389 {
2390     do_arglist(str, AL_SET, 0);
2391 }
2392 #endif
2393 
2394 /*
2395  * "what" == AL_SET: Redefine the argument list to 'str'.
2396  * "what" == AL_ADD: add files in 'str' to the argument list after "after".
2397  * "what" == AL_DEL: remove files in 'str' from the argument list.
2398  *
2399  * Return FAIL for failure, OK otherwise.
2400  */
2401     static int
2402 do_arglist(
2403     char_u	*str,
2404     int		what,
2405     int		after UNUSED)		/* 0 means before first one */
2406 {
2407     garray_T	new_ga;
2408     int		exp_count;
2409     char_u	**exp_files;
2410     int		i;
2411 #ifdef FEAT_LISTCMDS
2412     char_u	*p;
2413     int		match;
2414 #endif
2415     int		arg_escaped = TRUE;
2416 
2417     /*
2418      * Set default argument for ":argadd" command.
2419      */
2420     if (what == AL_ADD && *str == NUL)
2421     {
2422 	if (curbuf->b_ffname == NULL)
2423 	    return FAIL;
2424 	str = curbuf->b_fname;
2425 	arg_escaped = FALSE;
2426     }
2427 
2428     /*
2429      * Collect all file name arguments in "new_ga".
2430      */
2431     if (get_arglist(&new_ga, str, arg_escaped) == FAIL)
2432 	return FAIL;
2433 
2434 #ifdef FEAT_LISTCMDS
2435     if (what == AL_DEL)
2436     {
2437 	regmatch_T	regmatch;
2438 	int		didone;
2439 
2440 	/*
2441 	 * Delete the items: use each item as a regexp and find a match in the
2442 	 * argument list.
2443 	 */
2444 	regmatch.rm_ic = p_fic;	/* ignore case when 'fileignorecase' is set */
2445 	for (i = 0; i < new_ga.ga_len && !got_int; ++i)
2446 	{
2447 	    p = ((char_u **)new_ga.ga_data)[i];
2448 	    p = file_pat_to_reg_pat(p, NULL, NULL, FALSE);
2449 	    if (p == NULL)
2450 		break;
2451 	    regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
2452 	    if (regmatch.regprog == NULL)
2453 	    {
2454 		vim_free(p);
2455 		break;
2456 	    }
2457 
2458 	    didone = FALSE;
2459 	    for (match = 0; match < ARGCOUNT; ++match)
2460 		if (vim_regexec(&regmatch, alist_name(&ARGLIST[match]),
2461 								  (colnr_T)0))
2462 		{
2463 		    didone = TRUE;
2464 		    vim_free(ARGLIST[match].ae_fname);
2465 		    mch_memmove(ARGLIST + match, ARGLIST + match + 1,
2466 			    (ARGCOUNT - match - 1) * sizeof(aentry_T));
2467 		    --ALIST(curwin)->al_ga.ga_len;
2468 		    if (curwin->w_arg_idx > match)
2469 			--curwin->w_arg_idx;
2470 		    --match;
2471 		}
2472 
2473 	    vim_regfree(regmatch.regprog);
2474 	    vim_free(p);
2475 	    if (!didone)
2476 		EMSG2(_(e_nomatch2), ((char_u **)new_ga.ga_data)[i]);
2477 	}
2478 	ga_clear(&new_ga);
2479     }
2480     else
2481 #endif
2482     {
2483 	i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
2484 		&exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND);
2485 	ga_clear(&new_ga);
2486 	if (i == FAIL || exp_count == 0)
2487 	{
2488 	    EMSG(_(e_nomatch));
2489 	    return FAIL;
2490 	}
2491 
2492 #ifdef FEAT_LISTCMDS
2493 	if (what == AL_ADD)
2494 	{
2495 	    (void)alist_add_list(exp_count, exp_files, after);
2496 	    vim_free(exp_files);
2497 	}
2498 	else /* what == AL_SET */
2499 #endif
2500 	    alist_set(ALIST(curwin), exp_count, exp_files, FALSE, NULL, 0);
2501     }
2502 
2503     alist_check_arg_idx();
2504 
2505     return OK;
2506 }
2507 
2508 /*
2509  * Check the validity of the arg_idx for each other window.
2510  */
2511     static void
2512 alist_check_arg_idx(void)
2513 {
2514 #ifdef FEAT_WINDOWS
2515     win_T	*win;
2516     tabpage_T	*tp;
2517 
2518     FOR_ALL_TAB_WINDOWS(tp, win)
2519 	if (win->w_alist == curwin->w_alist)
2520 	    check_arg_idx(win);
2521 #else
2522     check_arg_idx(curwin);
2523 #endif
2524 }
2525 
2526 /*
2527  * Return TRUE if window "win" is editing the file at the current argument
2528  * index.
2529  */
2530     static int
2531 editing_arg_idx(win_T *win)
2532 {
2533     return !(win->w_arg_idx >= WARGCOUNT(win)
2534 		|| (win->w_buffer->b_fnum
2535 				      != WARGLIST(win)[win->w_arg_idx].ae_fnum
2536 		    && (win->w_buffer->b_ffname == NULL
2537 			 || !(fullpathcmp(
2538 				 alist_name(&WARGLIST(win)[win->w_arg_idx]),
2539 				win->w_buffer->b_ffname, TRUE) & FPC_SAME))));
2540 }
2541 
2542 /*
2543  * Check if window "win" is editing the w_arg_idx file in its argument list.
2544  */
2545     void
2546 check_arg_idx(win_T *win)
2547 {
2548     if (WARGCOUNT(win) > 1 && !editing_arg_idx(win))
2549     {
2550 	/* We are not editing the current entry in the argument list.
2551 	 * Set "arg_had_last" if we are editing the last one. */
2552 	win->w_arg_idx_invalid = TRUE;
2553 	if (win->w_arg_idx != WARGCOUNT(win) - 1
2554 		&& arg_had_last == FALSE
2555 #ifdef FEAT_WINDOWS
2556 		&& ALIST(win) == &global_alist
2557 #endif
2558 		&& GARGCOUNT > 0
2559 		&& win->w_arg_idx < GARGCOUNT
2560 		&& (win->w_buffer->b_fnum == GARGLIST[GARGCOUNT - 1].ae_fnum
2561 		    || (win->w_buffer->b_ffname != NULL
2562 			&& (fullpathcmp(alist_name(&GARGLIST[GARGCOUNT - 1]),
2563 				win->w_buffer->b_ffname, TRUE) & FPC_SAME))))
2564 	    arg_had_last = TRUE;
2565     }
2566     else
2567     {
2568 	/* We are editing the current entry in the argument list.
2569 	 * Set "arg_had_last" if it's also the last one */
2570 	win->w_arg_idx_invalid = FALSE;
2571 	if (win->w_arg_idx == WARGCOUNT(win) - 1
2572 #ifdef FEAT_WINDOWS
2573 		&& win->w_alist == &global_alist
2574 #endif
2575 		)
2576 	    arg_had_last = TRUE;
2577     }
2578 }
2579 
2580 /*
2581  * ":args", ":argslocal" and ":argsglobal".
2582  */
2583     void
2584 ex_args(exarg_T *eap)
2585 {
2586     int		i;
2587 
2588     if (eap->cmdidx != CMD_args)
2589     {
2590 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
2591 	alist_unlink(ALIST(curwin));
2592 	if (eap->cmdidx == CMD_argglobal)
2593 	    ALIST(curwin) = &global_alist;
2594 	else /* eap->cmdidx == CMD_arglocal */
2595 	    alist_new();
2596 #else
2597 	ex_ni(eap);
2598 	return;
2599 #endif
2600     }
2601 
2602     if (!ends_excmd(*eap->arg))
2603     {
2604 	/*
2605 	 * ":args file ..": define new argument list, handle like ":next"
2606 	 * Also for ":argslocal file .." and ":argsglobal file ..".
2607 	 */
2608 	ex_next(eap);
2609     }
2610     else
2611 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
2612 	if (eap->cmdidx == CMD_args)
2613 #endif
2614     {
2615 	/*
2616 	 * ":args": list arguments.
2617 	 */
2618 	if (ARGCOUNT > 0)
2619 	{
2620 	    /* Overwrite the command, for a short list there is no scrolling
2621 	     * required and no wait_return(). */
2622 	    gotocmdline(TRUE);
2623 	    for (i = 0; i < ARGCOUNT; ++i)
2624 	    {
2625 		if (i == curwin->w_arg_idx)
2626 		    msg_putchar('[');
2627 		msg_outtrans(alist_name(&ARGLIST[i]));
2628 		if (i == curwin->w_arg_idx)
2629 		    msg_putchar(']');
2630 		msg_putchar(' ');
2631 	    }
2632 	}
2633     }
2634 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
2635     else if (eap->cmdidx == CMD_arglocal)
2636     {
2637 	garray_T	*gap = &curwin->w_alist->al_ga;
2638 
2639 	/*
2640 	 * ":argslocal": make a local copy of the global argument list.
2641 	 */
2642 	if (ga_grow(gap, GARGCOUNT) == OK)
2643 	    for (i = 0; i < GARGCOUNT; ++i)
2644 		if (GARGLIST[i].ae_fname != NULL)
2645 		{
2646 		    AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname =
2647 					    vim_strsave(GARGLIST[i].ae_fname);
2648 		    AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
2649 							  GARGLIST[i].ae_fnum;
2650 		    ++gap->ga_len;
2651 		}
2652     }
2653 #endif
2654 }
2655 
2656 /*
2657  * ":previous", ":sprevious", ":Next" and ":sNext".
2658  */
2659     void
2660 ex_previous(exarg_T *eap)
2661 {
2662     /* If past the last one already, go to the last one. */
2663     if (curwin->w_arg_idx - (int)eap->line2 >= ARGCOUNT)
2664 	do_argfile(eap, ARGCOUNT - 1);
2665     else
2666 	do_argfile(eap, curwin->w_arg_idx - (int)eap->line2);
2667 }
2668 
2669 /*
2670  * ":rewind", ":first", ":sfirst" and ":srewind".
2671  */
2672     void
2673 ex_rewind(exarg_T *eap)
2674 {
2675     do_argfile(eap, 0);
2676 }
2677 
2678 /*
2679  * ":last" and ":slast".
2680  */
2681     void
2682 ex_last(exarg_T *eap)
2683 {
2684     do_argfile(eap, ARGCOUNT - 1);
2685 }
2686 
2687 /*
2688  * ":argument" and ":sargument".
2689  */
2690     void
2691 ex_argument(exarg_T *eap)
2692 {
2693     int		i;
2694 
2695     if (eap->addr_count > 0)
2696 	i = eap->line2 - 1;
2697     else
2698 	i = curwin->w_arg_idx;
2699     do_argfile(eap, i);
2700 }
2701 
2702 /*
2703  * Edit file "argn" of the argument lists.
2704  */
2705     void
2706 do_argfile(exarg_T *eap, int argn)
2707 {
2708     int		other;
2709     char_u	*p;
2710     int		old_arg_idx = curwin->w_arg_idx;
2711 
2712     if (argn < 0 || argn >= ARGCOUNT)
2713     {
2714 	if (ARGCOUNT <= 1)
2715 	    EMSG(_("E163: There is only one file to edit"));
2716 	else if (argn < 0)
2717 	    EMSG(_("E164: Cannot go before first file"));
2718 	else
2719 	    EMSG(_("E165: Cannot go beyond last file"));
2720     }
2721     else
2722     {
2723 	setpcmark();
2724 #ifdef FEAT_GUI
2725 	need_mouse_correct = TRUE;
2726 #endif
2727 
2728 #ifdef FEAT_WINDOWS
2729 	/* split window or create new tab page first */
2730 	if (*eap->cmd == 's' || cmdmod.tab != 0)
2731 	{
2732 	    if (win_split(0, 0) == FAIL)
2733 		return;
2734 	    RESET_BINDING(curwin);
2735 	}
2736 	else
2737 #endif
2738 	{
2739 	    /*
2740 	     * if 'hidden' set, only check for changed file when re-editing
2741 	     * the same buffer
2742 	     */
2743 	    other = TRUE;
2744 	    if (buf_hide(curbuf))
2745 	    {
2746 		p = fix_fname(alist_name(&ARGLIST[argn]));
2747 		other = otherfile(p);
2748 		vim_free(p);
2749 	    }
2750 	    if ((!buf_hide(curbuf) || !other)
2751 		  && check_changed(curbuf, CCGD_AW
2752 					 | (other ? 0 : CCGD_MULTWIN)
2753 					 | (eap->forceit ? CCGD_FORCEIT : 0)
2754 					 | CCGD_EXCMD))
2755 		return;
2756 	}
2757 
2758 	curwin->w_arg_idx = argn;
2759 	if (argn == ARGCOUNT - 1
2760 #ifdef FEAT_WINDOWS
2761 		&& curwin->w_alist == &global_alist
2762 #endif
2763 	   )
2764 	    arg_had_last = TRUE;
2765 
2766 	/* Edit the file; always use the last known line number.
2767 	 * When it fails (e.g. Abort for already edited file) restore the
2768 	 * argument index. */
2769 	if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
2770 		      eap, ECMD_LAST,
2771 		      (buf_hide(curwin->w_buffer) ? ECMD_HIDE : 0)
2772 			 + (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
2773 	    curwin->w_arg_idx = old_arg_idx;
2774 	/* like Vi: set the mark where the cursor is in the file. */
2775 	else if (eap->cmdidx != CMD_argdo)
2776 	    setmark('\'');
2777     }
2778 }
2779 
2780 /*
2781  * ":next", and commands that behave like it.
2782  */
2783     void
2784 ex_next(exarg_T *eap)
2785 {
2786     int		i;
2787 
2788     /*
2789      * check for changed buffer now, if this fails the argument list is not
2790      * redefined.
2791      */
2792     if (       buf_hide(curbuf)
2793 	    || eap->cmdidx == CMD_snext
2794 	    || !check_changed(curbuf, CCGD_AW
2795 				    | (eap->forceit ? CCGD_FORCEIT : 0)
2796 				    | CCGD_EXCMD))
2797     {
2798 	if (*eap->arg != NUL)		    /* redefine file list */
2799 	{
2800 	    if (do_arglist(eap->arg, AL_SET, 0) == FAIL)
2801 		return;
2802 	    i = 0;
2803 	}
2804 	else
2805 	    i = curwin->w_arg_idx + (int)eap->line2;
2806 	do_argfile(eap, i);
2807     }
2808 }
2809 
2810 #if defined(FEAT_LISTCMDS) || defined(PROTO)
2811 /*
2812  * ":argedit"
2813  */
2814     void
2815 ex_argedit(exarg_T *eap)
2816 {
2817     int i = eap->addr_count ? (int)eap->line2 : curwin->w_arg_idx + 1;
2818 
2819     if (do_arglist(eap->arg, AL_ADD, i) == FAIL)
2820 	return;
2821 #ifdef FEAT_TITLE
2822     maketitle();
2823 #endif
2824 
2825     if (curwin->w_arg_idx == 0 && (curbuf->b_ml.ml_flags & ML_EMPTY)
2826 	    && curbuf->b_ffname == NULL)
2827 	i = 0;
2828     /* Edit the argument. */
2829     if (i < ARGCOUNT)
2830 	do_argfile(eap, i);
2831 }
2832 
2833 /*
2834  * ":argadd"
2835  */
2836     void
2837 ex_argadd(exarg_T *eap)
2838 {
2839     do_arglist(eap->arg, AL_ADD,
2840 	       eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
2841 #ifdef FEAT_TITLE
2842     maketitle();
2843 #endif
2844 }
2845 
2846 /*
2847  * ":argdelete"
2848  */
2849     void
2850 ex_argdelete(exarg_T *eap)
2851 {
2852     int		i;
2853     int		n;
2854 
2855     if (eap->addr_count > 0)
2856     {
2857 	/* ":1,4argdel": Delete all arguments in the range. */
2858 	if (eap->line2 > ARGCOUNT)
2859 	    eap->line2 = ARGCOUNT;
2860 	n = eap->line2 - eap->line1 + 1;
2861 	if (*eap->arg != NUL)
2862 	    /* Can't have both a range and an argument. */
2863 	    EMSG(_(e_invarg));
2864 	else if (n <= 0)
2865 	{
2866 	    /* Don't give an error for ":%argdel" if the list is empty. */
2867 	    if (eap->line1 != 1 || eap->line2 != 0)
2868 		EMSG(_(e_invrange));
2869 	}
2870 	else
2871 	{
2872 	    for (i = eap->line1; i <= eap->line2; ++i)
2873 		vim_free(ARGLIST[i - 1].ae_fname);
2874 	    mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2,
2875 			(size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T)));
2876 	    ALIST(curwin)->al_ga.ga_len -= n;
2877 	    if (curwin->w_arg_idx >= eap->line2)
2878 		curwin->w_arg_idx -= n;
2879 	    else if (curwin->w_arg_idx > eap->line1)
2880 		curwin->w_arg_idx = eap->line1;
2881 	    if (ARGCOUNT == 0)
2882 		curwin->w_arg_idx = 0;
2883 	    else if (curwin->w_arg_idx >= ARGCOUNT)
2884 		curwin->w_arg_idx = ARGCOUNT - 1;
2885 	}
2886     }
2887     else if (*eap->arg == NUL)
2888 	EMSG(_(e_argreq));
2889     else
2890 	do_arglist(eap->arg, AL_DEL, 0);
2891 #ifdef FEAT_TITLE
2892     maketitle();
2893 #endif
2894 }
2895 
2896 /*
2897  * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo"
2898  */
2899     void
2900 ex_listdo(exarg_T *eap)
2901 {
2902     int		i;
2903 #ifdef FEAT_WINDOWS
2904     win_T	*wp;
2905     tabpage_T	*tp;
2906 #endif
2907     buf_T	*buf = curbuf;
2908     int		next_fnum = 0;
2909 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2910     char_u	*save_ei = NULL;
2911 #endif
2912     char_u	*p_shm_save;
2913 #ifdef FEAT_QUICKFIX
2914     int		qf_size = 0;
2915     int		qf_idx;
2916 #endif
2917 
2918 #ifndef FEAT_WINDOWS
2919     if (eap->cmdidx == CMD_windo)
2920     {
2921 	ex_ni(eap);
2922 	return;
2923     }
2924 #endif
2925 
2926 #ifndef FEAT_QUICKFIX
2927     if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo ||
2928 	    eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
2929     {
2930 	ex_ni(eap);
2931 	return;
2932     }
2933 #endif
2934 
2935 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2936     if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo)
2937 	/* Don't do syntax HL autocommands.  Skipping the syntax file is a
2938 	 * great speed improvement. */
2939 	save_ei = au_event_disable(",Syntax");
2940 #endif
2941 #ifdef FEAT_CLIPBOARD
2942     start_global_changes();
2943 #endif
2944 
2945     if (eap->cmdidx == CMD_windo
2946 	    || eap->cmdidx == CMD_tabdo
2947 	    || buf_hide(curbuf)
2948 	    || !check_changed(curbuf, CCGD_AW
2949 				    | (eap->forceit ? CCGD_FORCEIT : 0)
2950 				    | CCGD_EXCMD))
2951     {
2952 	i = 0;
2953 	/* start at the eap->line1 argument/window/buffer */
2954 #ifdef FEAT_WINDOWS
2955 	wp = firstwin;
2956 	tp = first_tabpage;
2957 #endif
2958 	switch (eap->cmdidx)
2959 	{
2960 #ifdef FEAT_WINDOWS
2961 	    case CMD_windo:
2962 		for ( ; wp != NULL && i + 1 < eap->line1; wp = wp->w_next)
2963 		    i++;
2964 		break;
2965 	    case CMD_tabdo:
2966 		for( ; tp != NULL && i + 1 < eap->line1; tp = tp->tp_next)
2967 		    i++;
2968 		break;
2969 #endif
2970 	    case CMD_argdo:
2971 		i = eap->line1 - 1;
2972 		break;
2973 	    default:
2974 		break;
2975 	}
2976 	/* set pcmark now */
2977 	if (eap->cmdidx == CMD_bufdo)
2978 	{
2979 	    /* Advance to the first listed buffer after "eap->line1". */
2980 	    for (buf = firstbuf; buf != NULL && (buf->b_fnum < eap->line1
2981 					  || !buf->b_p_bl); buf = buf->b_next)
2982 		if (buf->b_fnum > eap->line2)
2983 		{
2984 		    buf = NULL;
2985 		    break;
2986 		}
2987 	    if (buf != NULL)
2988 		goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum);
2989 	}
2990 #ifdef FEAT_QUICKFIX
2991 	else if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
2992 		|| eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
2993 	{
2994 	    qf_size = qf_get_size(eap);
2995 	    if (qf_size <= 0 || eap->line1 > qf_size)
2996 		buf = NULL;
2997 	    else
2998 	    {
2999 		ex_cc(eap);
3000 
3001 		buf = curbuf;
3002 		i = eap->line1 - 1;
3003 		if (eap->addr_count <= 0)
3004 		    /* default is all the quickfix/location list entries */
3005 		    eap->line2 = qf_size;
3006 	    }
3007 	}
3008 #endif
3009 	else
3010 	    setpcmark();
3011 	listcmd_busy = TRUE;	    /* avoids setting pcmark below */
3012 
3013 	while (!got_int && buf != NULL)
3014 	{
3015 	    if (eap->cmdidx == CMD_argdo)
3016 	    {
3017 		/* go to argument "i" */
3018 		if (i == ARGCOUNT)
3019 		    break;
3020 		/* Don't call do_argfile() when already there, it will try
3021 		 * reloading the file. */
3022 		if (curwin->w_arg_idx != i || !editing_arg_idx(curwin))
3023 		{
3024 		    /* Clear 'shm' to avoid that the file message overwrites
3025 		     * any output from the command. */
3026 		    p_shm_save = vim_strsave(p_shm);
3027 		    set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
3028 		    do_argfile(eap, i);
3029 		    set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
3030 		    vim_free(p_shm_save);
3031 		}
3032 		if (curwin->w_arg_idx != i)
3033 		    break;
3034 	    }
3035 #ifdef FEAT_WINDOWS
3036 	    else if (eap->cmdidx == CMD_windo)
3037 	    {
3038 		/* go to window "wp" */
3039 		if (!win_valid(wp))
3040 		    break;
3041 		win_goto(wp);
3042 		if (curwin != wp)
3043 		    break;  /* something must be wrong */
3044 		wp = curwin->w_next;
3045 	    }
3046 	    else if (eap->cmdidx == CMD_tabdo)
3047 	    {
3048 		/* go to window "tp" */
3049 		if (!valid_tabpage(tp))
3050 		    break;
3051 		goto_tabpage_tp(tp, TRUE, TRUE);
3052 		tp = tp->tp_next;
3053 	    }
3054 #endif
3055 	    else if (eap->cmdidx == CMD_bufdo)
3056 	    {
3057 		/* Remember the number of the next listed buffer, in case
3058 		 * ":bwipe" is used or autocommands do something strange. */
3059 		next_fnum = -1;
3060 		for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
3061 		    if (buf->b_p_bl)
3062 		    {
3063 			next_fnum = buf->b_fnum;
3064 			break;
3065 		    }
3066 	    }
3067 
3068 	    ++i;
3069 
3070 	    /* execute the command */
3071 	    do_cmdline(eap->arg, eap->getline, eap->cookie,
3072 						DOCMD_VERBOSE + DOCMD_NOWAIT);
3073 
3074 	    if (eap->cmdidx == CMD_bufdo)
3075 	    {
3076 		/* Done? */
3077 		if (next_fnum < 0 || next_fnum > eap->line2)
3078 		    break;
3079 		/* Check if the buffer still exists. */
3080 		FOR_ALL_BUFFERS(buf)
3081 		    if (buf->b_fnum == next_fnum)
3082 			break;
3083 		if (buf == NULL)
3084 		    break;
3085 
3086 		/* Go to the next buffer.  Clear 'shm' to avoid that the file
3087 		 * message overwrites any output from the command. */
3088 		p_shm_save = vim_strsave(p_shm);
3089 		set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
3090 		goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
3091 		set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
3092 		vim_free(p_shm_save);
3093 
3094 		/* If autocommands took us elsewhere, quit here. */
3095 		if (curbuf->b_fnum != next_fnum)
3096 		    break;
3097 	    }
3098 
3099 #ifdef FEAT_QUICKFIX
3100 	    if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
3101 		    || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
3102 	    {
3103 		if (i >= qf_size || i >= eap->line2)
3104 		    break;
3105 
3106 		qf_idx = qf_get_cur_idx(eap);
3107 
3108 		ex_cnext(eap);
3109 
3110 		/* If jumping to the next quickfix entry fails, quit here */
3111 		if (qf_get_cur_idx(eap) == qf_idx)
3112 		    break;
3113 	    }
3114 #endif
3115 
3116 	    if (eap->cmdidx == CMD_windo)
3117 	    {
3118 		validate_cursor();	/* cursor may have moved */
3119 #ifdef FEAT_SCROLLBIND
3120 		/* required when 'scrollbind' has been set */
3121 		if (curwin->w_p_scb)
3122 		    do_check_scrollbind(TRUE);
3123 #endif
3124 	    }
3125 
3126 #ifdef FEAT_WINDOWS
3127 	    if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo)
3128 		if (i+1 > eap->line2)
3129 		    break;
3130 #endif
3131 	    if (eap->cmdidx == CMD_argdo && i >= eap->line2)
3132 		break;
3133 	}
3134 	listcmd_busy = FALSE;
3135     }
3136 
3137 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
3138     if (save_ei != NULL)
3139     {
3140 	au_event_restore(save_ei);
3141 	apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
3142 					       curbuf->b_fname, TRUE, curbuf);
3143     }
3144 #endif
3145 #ifdef FEAT_CLIPBOARD
3146     end_global_changes();
3147 #endif
3148 }
3149 
3150 /*
3151  * Add files[count] to the arglist of the current window after arg "after".
3152  * The file names in files[count] must have been allocated and are taken over.
3153  * Files[] itself is not taken over.
3154  * Returns index of first added argument.  Returns -1 when failed (out of mem).
3155  */
3156     static int
3157 alist_add_list(
3158     int		count,
3159     char_u	**files,
3160     int		after)	    /* where to add: 0 = before first one */
3161 {
3162     int		i;
3163     int		old_argcount = ARGCOUNT;
3164 
3165     if (ga_grow(&ALIST(curwin)->al_ga, count) == OK)
3166     {
3167 	if (after < 0)
3168 	    after = 0;
3169 	if (after > ARGCOUNT)
3170 	    after = ARGCOUNT;
3171 	if (after < ARGCOUNT)
3172 	    mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
3173 				       (ARGCOUNT - after) * sizeof(aentry_T));
3174 	for (i = 0; i < count; ++i)
3175 	{
3176 	    ARGLIST[after + i].ae_fname = files[i];
3177 	    ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
3178 	}
3179 	ALIST(curwin)->al_ga.ga_len += count;
3180 	if (old_argcount > 0 && curwin->w_arg_idx >= after)
3181 	    curwin->w_arg_idx += count;
3182 	return after;
3183     }
3184 
3185     for (i = 0; i < count; ++i)
3186 	vim_free(files[i]);
3187     return -1;
3188 }
3189 
3190 #endif /* FEAT_LISTCMDS */
3191 
3192 #ifdef FEAT_EVAL
3193 /*
3194  * ":compiler[!] {name}"
3195  */
3196     void
3197 ex_compiler(exarg_T *eap)
3198 {
3199     char_u	*buf;
3200     char_u	*old_cur_comp = NULL;
3201     char_u	*p;
3202 
3203     if (*eap->arg == NUL)
3204     {
3205 	/* List all compiler scripts. */
3206 	do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')");
3207 					/* ) keep the indenter happy... */
3208     }
3209     else
3210     {
3211 	buf = alloc((unsigned)(STRLEN(eap->arg) + 14));
3212 	if (buf != NULL)
3213 	{
3214 	    if (eap->forceit)
3215 	    {
3216 		/* ":compiler! {name}" sets global options */
3217 		do_cmdline_cmd((char_u *)
3218 				   "command -nargs=* CompilerSet set <args>");
3219 	    }
3220 	    else
3221 	    {
3222 		/* ":compiler! {name}" sets local options.
3223 		 * To remain backwards compatible "current_compiler" is always
3224 		 * used.  A user's compiler plugin may set it, the distributed
3225 		 * plugin will then skip the settings.  Afterwards set
3226 		 * "b:current_compiler" and restore "current_compiler".
3227 		 * Explicitly prepend "g:" to make it work in a function. */
3228 		old_cur_comp = get_var_value((char_u *)"g:current_compiler");
3229 		if (old_cur_comp != NULL)
3230 		    old_cur_comp = vim_strsave(old_cur_comp);
3231 		do_cmdline_cmd((char_u *)
3232 			      "command -nargs=* CompilerSet setlocal <args>");
3233 	    }
3234 	    do_unlet((char_u *)"g:current_compiler", TRUE);
3235 	    do_unlet((char_u *)"b:current_compiler", TRUE);
3236 
3237 	    sprintf((char *)buf, "compiler/%s.vim", eap->arg);
3238 	    if (source_runtime(buf, DIP_ALL) == FAIL)
3239 		EMSG2(_("E666: compiler not supported: %s"), eap->arg);
3240 	    vim_free(buf);
3241 
3242 	    do_cmdline_cmd((char_u *)":delcommand CompilerSet");
3243 
3244 	    /* Set "b:current_compiler" from "current_compiler". */
3245 	    p = get_var_value((char_u *)"g:current_compiler");
3246 	    if (p != NULL)
3247 		set_internal_string_var((char_u *)"b:current_compiler", p);
3248 
3249 	    /* Restore "current_compiler" for ":compiler {name}". */
3250 	    if (!eap->forceit)
3251 	    {
3252 		if (old_cur_comp != NULL)
3253 		{
3254 		    set_internal_string_var((char_u *)"g:current_compiler",
3255 								old_cur_comp);
3256 		    vim_free(old_cur_comp);
3257 		}
3258 		else
3259 		    do_unlet((char_u *)"g:current_compiler", TRUE);
3260 	    }
3261 	}
3262     }
3263 }
3264 #endif
3265 
3266 /*
3267  * ":runtime [what] {name}"
3268  */
3269     void
3270 ex_runtime(exarg_T *eap)
3271 {
3272     char_u  *arg = eap->arg;
3273     char_u  *p = skiptowhite(arg);
3274     int	    len = (int)(p - arg);
3275     int	    flags = eap->forceit ? DIP_ALL : 0;
3276 
3277     if (STRNCMP(arg, "START", len) == 0)
3278     {
3279 	flags += DIP_START + DIP_NORTP;
3280 	arg = skipwhite(arg + len);
3281     }
3282     else if (STRNCMP(arg, "OPT", len) == 0)
3283     {
3284 	flags += DIP_OPT + DIP_NORTP;
3285 	arg = skipwhite(arg + len);
3286     }
3287     else if (STRNCMP(arg, "PACK", len) == 0)
3288     {
3289 	flags += DIP_START + DIP_OPT + DIP_NORTP;
3290 	arg = skipwhite(arg + len);
3291     }
3292     else if (STRNCMP(arg, "ALL", len) == 0)
3293     {
3294 	flags += DIP_START + DIP_OPT;
3295 	arg = skipwhite(arg + len);
3296     }
3297 
3298     source_runtime(arg, flags);
3299 }
3300 
3301     static void
3302 source_callback(char_u *fname, void *cookie UNUSED)
3303 {
3304     (void)do_source(fname, FALSE, DOSO_NONE);
3305 }
3306 
3307 /*
3308  * Find the file "name" in all directories in "path" and invoke
3309  * "callback(fname, cookie)".
3310  * "name" can contain wildcards.
3311  * When "flags" has DIP_ALL: source all files, otherwise only the first one.
3312  * When "flags" has DIP_DIR: find directories instead of files.
3313  * When "flags" has DIP_ERR: give an error message if there is no match.
3314  *
3315  * return FAIL when no file could be sourced, OK otherwise.
3316  */
3317     int
3318 do_in_path(
3319     char_u	*path,
3320     char_u	*name,
3321     int		flags,
3322     void	(*callback)(char_u *fname, void *ck),
3323     void	*cookie)
3324 {
3325     char_u	*rtp;
3326     char_u	*np;
3327     char_u	*buf;
3328     char_u	*rtp_copy;
3329     char_u	*tail;
3330     int		num_files;
3331     char_u	**files;
3332     int		i;
3333     int		did_one = FALSE;
3334 #ifdef AMIGA
3335     struct Process	*proc = (struct Process *)FindTask(0L);
3336     APTR		save_winptr = proc->pr_WindowPtr;
3337 
3338     /* Avoid a requester here for a volume that doesn't exist. */
3339     proc->pr_WindowPtr = (APTR)-1L;
3340 #endif
3341 
3342     /* Make a copy of 'runtimepath'.  Invoking the callback may change the
3343      * value. */
3344     rtp_copy = vim_strsave(path);
3345     buf = alloc(MAXPATHL);
3346     if (buf != NULL && rtp_copy != NULL)
3347     {
3348 	if (p_verbose > 1 && name != NULL)
3349 	{
3350 	    verbose_enter();
3351 	    smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
3352 						 (char *)name, (char *)path);
3353 	    verbose_leave();
3354 	}
3355 
3356 	/* Loop over all entries in 'runtimepath'. */
3357 	rtp = rtp_copy;
3358 	while (*rtp != NUL && ((flags & DIP_ALL) || !did_one))
3359 	{
3360 	    size_t buflen;
3361 
3362 	    /* Copy the path from 'runtimepath' to buf[]. */
3363 	    copy_option_part(&rtp, buf, MAXPATHL, ",");
3364 	    buflen = STRLEN(buf);
3365 
3366 	    /* Skip after or non-after directories. */
3367 	    if (flags & (DIP_NOAFTER | DIP_AFTER))
3368 	    {
3369 		int is_after = buflen >= 5
3370 				     && STRCMP(buf + buflen - 5, "after") == 0;
3371 
3372 		if ((is_after && (flags & DIP_NOAFTER))
3373 			|| (!is_after && (flags & DIP_AFTER)))
3374 		    continue;
3375 	    }
3376 
3377 	    if (name == NULL)
3378 	    {
3379 		(*callback)(buf, (void *) &cookie);
3380 		if (!did_one)
3381 		    did_one = (cookie == NULL);
3382 	    }
3383 	    else if (buflen + STRLEN(name) + 2 < MAXPATHL)
3384 	    {
3385 		add_pathsep(buf);
3386 		tail = buf + STRLEN(buf);
3387 
3388 		/* Loop over all patterns in "name" */
3389 		np = name;
3390 		while (*np != NUL && ((flags & DIP_ALL) || !did_one))
3391 		{
3392 		    /* Append the pattern from "name" to buf[]. */
3393 		    copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)),
3394 								       "\t ");
3395 
3396 		    if (p_verbose > 2)
3397 		    {
3398 			verbose_enter();
3399 			smsg((char_u *)_("Searching for \"%s\""), buf);
3400 			verbose_leave();
3401 		    }
3402 
3403 		    /* Expand wildcards, invoke the callback for each match. */
3404 		    if (gen_expand_wildcards(1, &buf, &num_files, &files,
3405 				  (flags & DIP_DIR) ? EW_DIR : EW_FILE) == OK)
3406 		    {
3407 			for (i = 0; i < num_files; ++i)
3408 			{
3409 			    (*callback)(files[i], cookie);
3410 			    did_one = TRUE;
3411 			    if (!(flags & DIP_ALL))
3412 				break;
3413 			}
3414 			FreeWild(num_files, files);
3415 		    }
3416 		}
3417 	    }
3418 	}
3419     }
3420     vim_free(buf);
3421     vim_free(rtp_copy);
3422     if (!did_one && name != NULL)
3423     {
3424 	char *basepath = path == p_rtp ? "runtimepath" : "packpath";
3425 
3426 	if (flags & DIP_ERR)
3427 	    EMSG3(_(e_dirnotf), basepath, name);
3428 	else if (p_verbose > 0)
3429 	{
3430 	    verbose_enter();
3431 	    smsg((char_u *)_("not found in '%s': \"%s\""), basepath, name);
3432 	    verbose_leave();
3433 	}
3434     }
3435 
3436 #ifdef AMIGA
3437     proc->pr_WindowPtr = save_winptr;
3438 #endif
3439 
3440     return did_one ? OK : FAIL;
3441 }
3442 
3443 /*
3444  * Find "name" in "path".  When found, invoke the callback function for
3445  * it: callback(fname, "cookie")
3446  * When "flags" has DIP_ALL repeat for all matches, otherwise only the first
3447  * one is used.
3448  * Returns OK when at least one match found, FAIL otherwise.
3449  *
3450  * If "name" is NULL calls callback for each entry in "path". Cookie is
3451  * passed by reference in this case, setting it to NULL indicates that callback
3452  * has done its job.
3453  */
3454     static int
3455 do_in_path_and_pp(
3456     char_u	*path,
3457     char_u	*name,
3458     int		flags,
3459     void	(*callback)(char_u *fname, void *ck),
3460     void	*cookie)
3461 {
3462     int		done = FAIL;
3463     char_u	*s;
3464     int		len;
3465     char	*start_dir = "pack/*/start/*/%s";
3466     char	*opt_dir = "pack/*/opt/*/%s";
3467 
3468     if ((flags & DIP_NORTP) == 0)
3469 	done = do_in_path(path, name, flags, callback, cookie);
3470 
3471     if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START))
3472     {
3473 	len = (int)(STRLEN(start_dir) + STRLEN(name));
3474 	s = alloc(len);
3475 	if (s == NULL)
3476 	    return FAIL;
3477 	vim_snprintf((char *)s, len, start_dir, name);
3478 	done = do_in_path(p_pp, s, flags, callback, cookie);
3479 	vim_free(s);
3480     }
3481 
3482     if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_OPT))
3483     {
3484 	len = (int)(STRLEN(opt_dir) + STRLEN(name));
3485 	s = alloc(len);
3486 	if (s == NULL)
3487 	    return FAIL;
3488 	vim_snprintf((char *)s, len, opt_dir, name);
3489 	done = do_in_path(p_pp, s, flags, callback, cookie);
3490 	vim_free(s);
3491     }
3492 
3493     return done;
3494 }
3495 
3496 /*
3497  * Just like do_in_path_and_pp(), using 'runtimepath' for "path".
3498  */
3499     int
3500 do_in_runtimepath(
3501     char_u	*name,
3502     int		flags,
3503     void	(*callback)(char_u *fname, void *ck),
3504     void	*cookie)
3505 {
3506     return do_in_path_and_pp(p_rtp, name, flags, callback, cookie);
3507 }
3508 
3509 /*
3510  * Source the file "name" from all directories in 'runtimepath'.
3511  * "name" can contain wildcards.
3512  * When "flags" has DIP_ALL: source all files, otherwise only the first one.
3513  *
3514  * return FAIL when no file could be sourced, OK otherwise.
3515  */
3516     int
3517 source_runtime(char_u *name, int flags)
3518 {
3519     return source_in_path(p_rtp, name, flags);
3520 }
3521 
3522 /*
3523  * Just like source_runtime(), but use "path" instead of 'runtimepath'.
3524  */
3525     int
3526 source_in_path(char_u *path, char_u *name, int flags)
3527 {
3528     return do_in_path_and_pp(path, name, flags, source_callback, NULL);
3529 }
3530 
3531 
3532 /*
3533  * Expand wildcards in "pat" and invoke do_source() for each match.
3534  */
3535     static void
3536 source_all_matches(char_u *pat)
3537 {
3538     int	    num_files;
3539     char_u  **files;
3540     int	    i;
3541 
3542     if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK)
3543     {
3544 	for (i = 0; i < num_files; ++i)
3545 	    (void)do_source(files[i], FALSE, DOSO_NONE);
3546 	FreeWild(num_files, files);
3547     }
3548 }
3549 
3550 /* used for "cookie" of add_pack_plugin() */
3551 static int APP_ADD_DIR;
3552 static int APP_LOAD;
3553 static int APP_BOTH;
3554 
3555     static void
3556 add_pack_plugin(char_u *fname, void *cookie)
3557 {
3558     char_u  *p4, *p3, *p2, *p1, *p;
3559     char_u  *insp;
3560     int	    c;
3561     char_u  *new_rtp;
3562     int	    keep;
3563     size_t  oldlen;
3564     size_t  addlen;
3565     char_u  *afterdir;
3566     size_t  afterlen = 0;
3567     char_u  *ffname = fix_fname(fname);
3568     size_t  fname_len;
3569     char_u  *buf = NULL;
3570     char_u  *rtp_ffname;
3571     int	    match;
3572 
3573     if (ffname == NULL)
3574 	return;
3575     if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)ffname) == NULL)
3576     {
3577 	/* directory is not yet in 'runtimepath', add it */
3578 	p4 = p3 = p2 = p1 = get_past_head(ffname);
3579 	for (p = p1; *p; MB_PTR_ADV(p))
3580 	    if (vim_ispathsep_nocolon(*p))
3581 	    {
3582 		p4 = p3; p3 = p2; p2 = p1; p1 = p;
3583 	    }
3584 
3585 	/* now we have:
3586 	 * rtp/pack/name/start/name
3587 	 *    p4   p3   p2    p1
3588 	 *
3589 	 * find the part up to "pack" in 'runtimepath' */
3590 	c = *p4;
3591 	*p4 = NUL;
3592 
3593 	/* Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. */
3594 	fname_len = STRLEN(ffname);
3595 	insp = p_rtp;
3596 	buf = alloc(MAXPATHL);
3597 	if (buf == NULL)
3598 	    goto theend;
3599 	while (*insp != NUL)
3600 	{
3601 	    copy_option_part(&insp, buf, MAXPATHL, ",");
3602 	    add_pathsep(buf);
3603 	    rtp_ffname = fix_fname(buf);
3604 	    if (rtp_ffname == NULL)
3605 		goto theend;
3606 	    match = vim_fnamencmp(rtp_ffname, ffname, fname_len) == 0;
3607 	    vim_free(rtp_ffname);
3608 	    if (match)
3609 		break;
3610 	}
3611 
3612 	if (*insp == NUL)
3613 	    /* not found, append at the end */
3614 	    insp = p_rtp + STRLEN(p_rtp);
3615 	else
3616 	    /* append after the matching directory. */
3617 	    --insp;
3618 	*p4 = c;
3619 
3620 	/* check if rtp/pack/name/start/name/after exists */
3621 	afterdir = concat_fnames(ffname, (char_u *)"after", TRUE);
3622 	if (afterdir != NULL && mch_isdir(afterdir))
3623 	    afterlen = STRLEN(afterdir) + 1; /* add one for comma */
3624 
3625 	oldlen = STRLEN(p_rtp);
3626 	addlen = STRLEN(ffname) + 1; /* add one for comma */
3627 	new_rtp = alloc((int)(oldlen + addlen + afterlen + 1));
3628 							  /* add one for NUL */
3629 	if (new_rtp == NULL)
3630 	    goto theend;
3631 	keep = (int)(insp - p_rtp);
3632 	mch_memmove(new_rtp, p_rtp, keep);
3633 	new_rtp[keep] = ',';
3634 	mch_memmove(new_rtp + keep + 1, ffname, addlen);
3635 	if (p_rtp[keep] != NUL)
3636 	    mch_memmove(new_rtp + keep + addlen, p_rtp + keep,
3637 							   oldlen - keep + 1);
3638 	if (afterlen > 0)
3639 	{
3640 	    STRCAT(new_rtp, ",");
3641 	    STRCAT(new_rtp, afterdir);
3642 	}
3643 	set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
3644 	vim_free(new_rtp);
3645 	vim_free(afterdir);
3646     }
3647 
3648     if (cookie != &APP_ADD_DIR)
3649     {
3650 	static char *plugpat = "%s/plugin/**/*.vim";
3651 	static char *ftpat = "%s/ftdetect/*.vim";
3652 	int	    len;
3653 	char_u	    *pat;
3654 
3655 	len = (int)STRLEN(ffname) + (int)STRLEN(ftpat);
3656 	pat = alloc(len);
3657 	if (pat == NULL)
3658 	    goto theend;
3659 	vim_snprintf((char *)pat, len, plugpat, ffname);
3660 	source_all_matches(pat);
3661 
3662 #ifdef FEAT_AUTOCMD
3663 	{
3664 	    char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes");
3665 
3666 	    /* If runtime/filetype.vim wasn't loaded yet, the scripts will be
3667 	     * found when it loads. */
3668 	    if (cmd != NULL && eval_to_number(cmd) > 0)
3669 	    {
3670 		do_cmdline_cmd((char_u *)"augroup filetypedetect");
3671 		vim_snprintf((char *)pat, len, ftpat, ffname);
3672 		source_all_matches(pat);
3673 		do_cmdline_cmd((char_u *)"augroup END");
3674 	    }
3675 	    vim_free(cmd);
3676 	}
3677 #endif
3678 	vim_free(pat);
3679     }
3680 
3681 theend:
3682     vim_free(buf);
3683     vim_free(ffname);
3684 }
3685 
3686 /*
3687  * Add all packages in the "start" directory to 'runtimepath'.
3688  */
3689     void
3690 add_pack_start_dirs(void)
3691 {
3692     do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR,
3693 					       add_pack_plugin, &APP_ADD_DIR);
3694 }
3695 
3696 /*
3697  * Load plugins from all packages in the "start" directory.
3698  */
3699     void
3700 load_start_packages(void)
3701 {
3702     did_source_packages = TRUE;
3703     do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR,
3704 						  add_pack_plugin, &APP_LOAD);
3705 }
3706 
3707 /*
3708  * ":packloadall"
3709  * Find plugins in the package directories and source them.
3710  */
3711     void
3712 ex_packloadall(exarg_T *eap)
3713 {
3714     if (!did_source_packages || eap->forceit)
3715     {
3716 	/* First do a round to add all directories to 'runtimepath', then load
3717 	 * the plugins. This allows for plugins to use an autoload directory
3718 	 * of another plugin. */
3719 	add_pack_start_dirs();
3720 	load_start_packages();
3721     }
3722 }
3723 
3724 /*
3725  * ":packadd[!] {name}"
3726  */
3727     void
3728 ex_packadd(exarg_T *eap)
3729 {
3730     static char *plugpat = "pack/*/opt/%s";
3731     int		len;
3732     char	*pat;
3733 
3734     len = (int)STRLEN(plugpat) + (int)STRLEN(eap->arg);
3735     pat = (char *)alloc(len);
3736     if (pat == NULL)
3737 	return;
3738     vim_snprintf(pat, len, plugpat, eap->arg);
3739     do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR + DIP_ERR,
3740 		    add_pack_plugin, eap->forceit ? &APP_ADD_DIR : &APP_BOTH);
3741     vim_free(pat);
3742 }
3743 
3744 #if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
3745 /*
3746  * ":options"
3747  */
3748     void
3749 ex_options(
3750     exarg_T	*eap UNUSED)
3751 {
3752     cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
3753 }
3754 #endif
3755 
3756 #if defined(FEAT_PYTHON3) || defined(FEAT_PYTHON) || defined(PROTO)
3757 
3758 # if (defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)) || defined(PROTO)
3759 /*
3760  * Detect Python 3 or 2, and initialize 'pyxversion'.
3761  */
3762     void
3763 init_pyxversion(void)
3764 {
3765     if (p_pyx == 0)
3766     {
3767 	if (python3_enabled(FALSE))
3768 	    p_pyx = 3;
3769 	else if (python_enabled(FALSE))
3770 	    p_pyx = 2;
3771     }
3772 }
3773 # endif
3774 
3775 /*
3776  * Does a file contain one of the following strings at the beginning of any
3777  * line?
3778  * "#!(any string)python2"  => returns 2
3779  * "#!(any string)python3"  => returns 3
3780  * "# requires python 2.x"  => returns 2
3781  * "# requires python 3.x"  => returns 3
3782  * otherwise return 0.
3783  */
3784     static int
3785 requires_py_version(char_u *filename)
3786 {
3787     FILE    *file;
3788     int	    requires_py_version = 0;
3789     int	    i, lines;
3790 
3791     lines = (int)p_mls;
3792     if (lines < 0)
3793 	lines = 5;
3794 
3795     file = mch_fopen((char *)filename, "r");
3796     if (file != NULL)
3797     {
3798 	for (i = 0; i < lines; i++)
3799 	{
3800 	    if (vim_fgets(IObuff, IOSIZE, file))
3801 		break;
3802 	    if (i == 0 && IObuff[0] == '#' && IObuff[1] == '!')
3803 	    {
3804 		/* Check shebang. */
3805 		if (strstr((char *)IObuff + 2, "python2") != NULL)
3806 		{
3807 		    requires_py_version = 2;
3808 		    break;
3809 		}
3810 		if (strstr((char *)IObuff + 2, "python3") != NULL)
3811 		{
3812 		    requires_py_version = 3;
3813 		    break;
3814 		}
3815 	    }
3816 	    IObuff[21] = '\0';
3817 	    if (STRCMP("# requires python 2.x", IObuff) == 0)
3818 	    {
3819 		requires_py_version = 2;
3820 		break;
3821 	    }
3822 	    if (STRCMP("# requires python 3.x", IObuff) == 0)
3823 	    {
3824 		requires_py_version = 3;
3825 		break;
3826 	    }
3827 	}
3828 	fclose(file);
3829     }
3830     return requires_py_version;
3831 }
3832 
3833 
3834 /*
3835  * Source a python file using the requested python version.
3836  */
3837     static void
3838 source_pyx_file(exarg_T *eap, char_u *fname)
3839 {
3840     exarg_T ex;
3841     int	    v = requires_py_version(fname);
3842 
3843 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
3844     init_pyxversion();
3845 # endif
3846     if (v == 0)
3847     {
3848 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
3849 	/* user didn't choose a preference, 'pyx' is used */
3850 	v = p_pyx;
3851 # elif defined(FEAT_PYTHON)
3852 	v = 2;
3853 # elif defined(FEAT_PYTHON3)
3854 	v = 3;
3855 # endif
3856     }
3857 
3858     /*
3859      * now source, if required python version is not supported show
3860      * unobtrusive message.
3861      */
3862     if (eap == NULL)
3863 	vim_memset(&ex, 0, sizeof(ex));
3864     else
3865 	ex = *eap;
3866     ex.arg = fname;
3867     ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3");
3868 
3869     if (v == 2)
3870     {
3871 # ifdef FEAT_PYTHON
3872 	ex_pyfile(&ex);
3873 # else
3874 	vim_snprintf((char *)IObuff, IOSIZE,
3875 		_("W20: Required python version 2.x not supported, ignoring file: %s"),
3876 		fname);
3877 	MSG(IObuff);
3878 # endif
3879 	return;
3880     }
3881     else
3882     {
3883 # ifdef FEAT_PYTHON3
3884 	ex_py3file(&ex);
3885 # else
3886 	vim_snprintf((char *)IObuff, IOSIZE,
3887 		_("W21: Required python version 3.x not supported, ignoring file: %s"),
3888 		fname);
3889 	MSG(IObuff);
3890 # endif
3891 	return;
3892     }
3893 }
3894 
3895 /*
3896  * ":pyxfile {fname}"
3897  */
3898     void
3899 ex_pyxfile(exarg_T *eap)
3900 {
3901     source_pyx_file(eap, eap->arg);
3902 }
3903 
3904 /*
3905  * ":pyx"
3906  */
3907     void
3908 ex_pyx(exarg_T *eap)
3909 {
3910 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
3911     init_pyxversion();
3912     if (p_pyx == 2)
3913 	ex_python(eap);
3914     else
3915 	ex_py3(eap);
3916 # elif defined(FEAT_PYTHON)
3917     ex_python(eap);
3918 # elif defined(FEAT_PYTHON3)
3919     ex_py3(eap);
3920 # endif
3921 }
3922 
3923 /*
3924  * ":pyxdo"
3925  */
3926     void
3927 ex_pyxdo(exarg_T *eap)
3928 {
3929 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
3930     init_pyxversion();
3931     if (p_pyx == 2)
3932 	ex_pydo(eap);
3933     else
3934 	ex_py3do(eap);
3935 # elif defined(FEAT_PYTHON)
3936     ex_pydo(eap);
3937 # elif defined(FEAT_PYTHON3)
3938     ex_py3do(eap);
3939 # endif
3940 }
3941 
3942 #endif
3943 
3944 /*
3945  * ":source {fname}"
3946  */
3947     void
3948 ex_source(exarg_T *eap)
3949 {
3950 #ifdef FEAT_BROWSE
3951     if (cmdmod.browse)
3952     {
3953 	char_u *fname = NULL;
3954 
3955 	fname = do_browse(0, (char_u *)_("Source Vim script"), eap->arg,
3956 				      NULL, NULL, BROWSE_FILTER_MACROS, NULL);
3957 	if (fname != NULL)
3958 	{
3959 	    cmd_source(fname, eap);
3960 	    vim_free(fname);
3961 	}
3962     }
3963     else
3964 #endif
3965 	cmd_source(eap->arg, eap);
3966 }
3967 
3968     static void
3969 cmd_source(char_u *fname, exarg_T *eap)
3970 {
3971     if (*fname == NUL)
3972 	EMSG(_(e_argreq));
3973 
3974     else if (eap != NULL && eap->forceit)
3975 	/* ":source!": read Normal mode commands
3976 	 * Need to execute the commands directly.  This is required at least
3977 	 * for:
3978 	 * - ":g" command busy
3979 	 * - after ":argdo", ":windo" or ":bufdo"
3980 	 * - another command follows
3981 	 * - inside a loop
3982 	 */
3983 	openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL
3984 #ifdef FEAT_EVAL
3985 						 || eap->cstack->cs_idx >= 0
3986 #endif
3987 						 );
3988 
3989     /* ":source" read ex commands */
3990     else if (do_source(fname, FALSE, DOSO_NONE) == FAIL)
3991 	EMSG2(_(e_notopen), fname);
3992 }
3993 
3994 /*
3995  * ":source" and associated commands.
3996  */
3997 /*
3998  * Structure used to store info for each sourced file.
3999  * It is shared between do_source() and getsourceline().
4000  * This is required, because it needs to be handed to do_cmdline() and
4001  * sourcing can be done recursively.
4002  */
4003 struct source_cookie
4004 {
4005     FILE	*fp;		/* opened file for sourcing */
4006     char_u      *nextline;      /* if not NULL: line that was read ahead */
4007     int		finished;	/* ":finish" used */
4008 #if defined(USE_CRNL) || defined(USE_CR)
4009     int		fileformat;	/* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
4010     int		error;		/* TRUE if LF found after CR-LF */
4011 #endif
4012 #ifdef FEAT_EVAL
4013     linenr_T	breakpoint;	/* next line with breakpoint or zero */
4014     char_u	*fname;		/* name of sourced file */
4015     int		dbg_tick;	/* debug_tick when breakpoint was set */
4016     int		level;		/* top nesting level of sourced file */
4017 #endif
4018 #ifdef FEAT_MBYTE
4019     vimconv_T	conv;		/* type of conversion */
4020 #endif
4021 };
4022 
4023 #ifdef FEAT_EVAL
4024 /*
4025  * Return the address holding the next breakpoint line for a source cookie.
4026  */
4027     linenr_T *
4028 source_breakpoint(void *cookie)
4029 {
4030     return &((struct source_cookie *)cookie)->breakpoint;
4031 }
4032 
4033 /*
4034  * Return the address holding the debug tick for a source cookie.
4035  */
4036     int *
4037 source_dbg_tick(void *cookie)
4038 {
4039     return &((struct source_cookie *)cookie)->dbg_tick;
4040 }
4041 
4042 /*
4043  * Return the nesting level for a source cookie.
4044  */
4045     int
4046 source_level(void *cookie)
4047 {
4048     return ((struct source_cookie *)cookie)->level;
4049 }
4050 #endif
4051 
4052 static char_u *get_one_sourceline(struct source_cookie *sp);
4053 
4054 #if (defined(WIN32) && defined(FEAT_CSCOPE)) || defined(HAVE_FD_CLOEXEC)
4055 # define USE_FOPEN_NOINH
4056 static FILE *fopen_noinh_readbin(char *filename);
4057 
4058 /*
4059  * Special function to open a file without handle inheritance.
4060  * When possible the handle is closed on exec().
4061  */
4062     static FILE *
4063 fopen_noinh_readbin(char *filename)
4064 {
4065 # ifdef WIN32
4066     int	fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0);
4067 # else
4068     int	fd_tmp = mch_open(filename, O_RDONLY, 0);
4069 # endif
4070 
4071     if (fd_tmp == -1)
4072 	return NULL;
4073 
4074 # ifdef HAVE_FD_CLOEXEC
4075     {
4076 	int fdflags = fcntl(fd_tmp, F_GETFD);
4077 	if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
4078 	    (void)fcntl(fd_tmp, F_SETFD, fdflags | FD_CLOEXEC);
4079     }
4080 # endif
4081 
4082     return fdopen(fd_tmp, READBIN);
4083 }
4084 #endif
4085 
4086 
4087 /*
4088  * do_source: Read the file "fname" and execute its lines as EX commands.
4089  *
4090  * This function may be called recursively!
4091  *
4092  * return FAIL if file could not be opened, OK otherwise
4093  */
4094     int
4095 do_source(
4096     char_u	*fname,
4097     int		check_other,	    /* check for .vimrc and _vimrc */
4098     int		is_vimrc)	    /* DOSO_ value */
4099 {
4100     struct source_cookie    cookie;
4101     char_u		    *save_sourcing_name;
4102     linenr_T		    save_sourcing_lnum;
4103     char_u		    *p;
4104     char_u		    *fname_exp;
4105     char_u		    *firstline = NULL;
4106     int			    retval = FAIL;
4107 #ifdef FEAT_EVAL
4108     scid_T		    save_current_SID;
4109     static scid_T	    last_current_SID = 0;
4110     void		    *save_funccalp;
4111     int			    save_debug_break_level = debug_break_level;
4112     scriptitem_T	    *si = NULL;
4113 # ifdef UNIX
4114     stat_T		    st;
4115     int			    stat_ok;
4116 # endif
4117 #endif
4118 #ifdef STARTUPTIME
4119     struct timeval	    tv_rel;
4120     struct timeval	    tv_start;
4121 #endif
4122 #ifdef FEAT_PROFILE
4123     proftime_T		    wait_start;
4124 #endif
4125 
4126     p = expand_env_save(fname);
4127     if (p == NULL)
4128 	return retval;
4129     fname_exp = fix_fname(p);
4130     vim_free(p);
4131     if (fname_exp == NULL)
4132 	return retval;
4133     if (mch_isdir(fname_exp))
4134     {
4135 	smsg((char_u *)_("Cannot source a directory: \"%s\""), fname);
4136 	goto theend;
4137     }
4138 
4139 #ifdef FEAT_AUTOCMD
4140     /* Apply SourceCmd autocommands, they should get the file and source it. */
4141     if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
4142 	    && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
4143 							       FALSE, curbuf))
4144     {
4145 # ifdef FEAT_EVAL
4146 	retval = aborting() ? FAIL : OK;
4147 # else
4148 	retval = OK;
4149 # endif
4150 	goto theend;
4151     }
4152 
4153     /* Apply SourcePre autocommands, they may get the file. */
4154     apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
4155 #endif
4156 
4157 #ifdef USE_FOPEN_NOINH
4158     cookie.fp = fopen_noinh_readbin((char *)fname_exp);
4159 #else
4160     cookie.fp = mch_fopen((char *)fname_exp, READBIN);
4161 #endif
4162     if (cookie.fp == NULL && check_other)
4163     {
4164 	/*
4165 	 * Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
4166 	 * and ".exrc" by "_exrc" or vice versa.
4167 	 */
4168 	p = gettail(fname_exp);
4169 	if ((*p == '.' || *p == '_')
4170 		&& (STRICMP(p + 1, "vimrc") == 0
4171 		    || STRICMP(p + 1, "gvimrc") == 0
4172 		    || STRICMP(p + 1, "exrc") == 0))
4173 	{
4174 	    if (*p == '_')
4175 		*p = '.';
4176 	    else
4177 		*p = '_';
4178 #ifdef USE_FOPEN_NOINH
4179 	    cookie.fp = fopen_noinh_readbin((char *)fname_exp);
4180 #else
4181 	    cookie.fp = mch_fopen((char *)fname_exp, READBIN);
4182 #endif
4183 	}
4184     }
4185 
4186     if (cookie.fp == NULL)
4187     {
4188 	if (p_verbose > 0)
4189 	{
4190 	    verbose_enter();
4191 	    if (sourcing_name == NULL)
4192 		smsg((char_u *)_("could not source \"%s\""), fname);
4193 	    else
4194 		smsg((char_u *)_("line %ld: could not source \"%s\""),
4195 							sourcing_lnum, fname);
4196 	    verbose_leave();
4197 	}
4198 	goto theend;
4199     }
4200 
4201     /*
4202      * The file exists.
4203      * - In verbose mode, give a message.
4204      * - For a vimrc file, may want to set 'compatible', call vimrc_found().
4205      */
4206     if (p_verbose > 1)
4207     {
4208 	verbose_enter();
4209 	if (sourcing_name == NULL)
4210 	    smsg((char_u *)_("sourcing \"%s\""), fname);
4211 	else
4212 	    smsg((char_u *)_("line %ld: sourcing \"%s\""),
4213 							sourcing_lnum, fname);
4214 	verbose_leave();
4215     }
4216     if (is_vimrc == DOSO_VIMRC)
4217 	vimrc_found(fname_exp, (char_u *)"MYVIMRC");
4218     else if (is_vimrc == DOSO_GVIMRC)
4219 	vimrc_found(fname_exp, (char_u *)"MYGVIMRC");
4220 
4221 #ifdef USE_CRNL
4222     /* If no automatic file format: Set default to CR-NL. */
4223     if (*p_ffs == NUL)
4224 	cookie.fileformat = EOL_DOS;
4225     else
4226 	cookie.fileformat = EOL_UNKNOWN;
4227     cookie.error = FALSE;
4228 #endif
4229 
4230 #ifdef USE_CR
4231     /* If no automatic file format: Set default to CR. */
4232     if (*p_ffs == NUL)
4233 	cookie.fileformat = EOL_MAC;
4234     else
4235 	cookie.fileformat = EOL_UNKNOWN;
4236     cookie.error = FALSE;
4237 #endif
4238 
4239     cookie.nextline = NULL;
4240     cookie.finished = FALSE;
4241 
4242 #ifdef FEAT_EVAL
4243     /*
4244      * Check if this script has a breakpoint.
4245      */
4246     cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
4247     cookie.fname = fname_exp;
4248     cookie.dbg_tick = debug_tick;
4249 
4250     cookie.level = ex_nesting_level;
4251 #endif
4252 
4253     /*
4254      * Keep the sourcing name/lnum, for recursive calls.
4255      */
4256     save_sourcing_name = sourcing_name;
4257     sourcing_name = fname_exp;
4258     save_sourcing_lnum = sourcing_lnum;
4259     sourcing_lnum = 0;
4260 
4261 #ifdef FEAT_MBYTE
4262     cookie.conv.vc_type = CONV_NONE;		/* no conversion */
4263 
4264     /* Read the first line so we can check for a UTF-8 BOM. */
4265     firstline = getsourceline(0, (void *)&cookie, 0);
4266     if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
4267 			      && firstline[1] == 0xbb && firstline[2] == 0xbf)
4268     {
4269 	/* Found BOM; setup conversion, skip over BOM and recode the line. */
4270 	convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
4271 	p = string_convert(&cookie.conv, firstline + 3, NULL);
4272 	if (p == NULL)
4273 	    p = vim_strsave(firstline + 3);
4274 	if (p != NULL)
4275 	{
4276 	    vim_free(firstline);
4277 	    firstline = p;
4278 	}
4279     }
4280 #endif
4281 
4282 #ifdef STARTUPTIME
4283     if (time_fd != NULL)
4284 	time_push(&tv_rel, &tv_start);
4285 #endif
4286 
4287 #ifdef FEAT_EVAL
4288 # ifdef FEAT_PROFILE
4289     if (do_profiling == PROF_YES)
4290 	prof_child_enter(&wait_start);		/* entering a child now */
4291 # endif
4292 
4293     /* Don't use local function variables, if called from a function.
4294      * Also starts profiling timer for nested script. */
4295     save_funccalp = save_funccal();
4296 
4297     /*
4298      * Check if this script was sourced before to finds its SID.
4299      * If it's new, generate a new SID.
4300      */
4301     save_current_SID = current_SID;
4302 # ifdef UNIX
4303     stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
4304 # endif
4305     for (current_SID = script_items.ga_len; current_SID > 0; --current_SID)
4306     {
4307 	si = &SCRIPT_ITEM(current_SID);
4308 	if (si->sn_name != NULL
4309 		&& (
4310 # ifdef UNIX
4311 		    /* Compare dev/ino when possible, it catches symbolic
4312 		     * links.  Also compare file names, the inode may change
4313 		     * when the file was edited. */
4314 		    ((stat_ok && si->sn_dev_valid)
4315 			&& (si->sn_dev == st.st_dev
4316 			    && si->sn_ino == st.st_ino)) ||
4317 # endif
4318 		fnamecmp(si->sn_name, fname_exp) == 0))
4319 	    break;
4320     }
4321     if (current_SID == 0)
4322     {
4323 	current_SID = ++last_current_SID;
4324 	if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len))
4325 								      == FAIL)
4326 	    goto almosttheend;
4327 	while (script_items.ga_len < current_SID)
4328 	{
4329 	    ++script_items.ga_len;
4330 	    SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
4331 # ifdef FEAT_PROFILE
4332 	    SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
4333 # endif
4334 	}
4335 	si = &SCRIPT_ITEM(current_SID);
4336 	si->sn_name = fname_exp;
4337 	fname_exp = NULL;
4338 # ifdef UNIX
4339 	if (stat_ok)
4340 	{
4341 	    si->sn_dev_valid = TRUE;
4342 	    si->sn_dev = st.st_dev;
4343 	    si->sn_ino = st.st_ino;
4344 	}
4345 	else
4346 	    si->sn_dev_valid = FALSE;
4347 # endif
4348 
4349 	/* Allocate the local script variables to use for this script. */
4350 	new_script_vars(current_SID);
4351     }
4352 
4353 # ifdef FEAT_PROFILE
4354     if (do_profiling == PROF_YES)
4355     {
4356 	int	forceit;
4357 
4358 	/* Check if we do profiling for this script. */
4359 	if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit))
4360 	{
4361 	    script_do_profile(si);
4362 	    si->sn_pr_force = forceit;
4363 	}
4364 	if (si->sn_prof_on)
4365 	{
4366 	    ++si->sn_pr_count;
4367 	    profile_start(&si->sn_pr_start);
4368 	    profile_zero(&si->sn_pr_children);
4369 	}
4370     }
4371 # endif
4372 #endif
4373 
4374     /*
4375      * Call do_cmdline, which will call getsourceline() to get the lines.
4376      */
4377     do_cmdline(firstline, getsourceline, (void *)&cookie,
4378 				     DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
4379     retval = OK;
4380 
4381 #ifdef FEAT_PROFILE
4382     if (do_profiling == PROF_YES)
4383     {
4384 	/* Get "si" again, "script_items" may have been reallocated. */
4385 	si = &SCRIPT_ITEM(current_SID);
4386 	if (si->sn_prof_on)
4387 	{
4388 	    profile_end(&si->sn_pr_start);
4389 	    profile_sub_wait(&wait_start, &si->sn_pr_start);
4390 	    profile_add(&si->sn_pr_total, &si->sn_pr_start);
4391 	    profile_self(&si->sn_pr_self, &si->sn_pr_start,
4392 							 &si->sn_pr_children);
4393 	}
4394     }
4395 #endif
4396 
4397     if (got_int)
4398 	EMSG(_(e_interr));
4399     sourcing_name = save_sourcing_name;
4400     sourcing_lnum = save_sourcing_lnum;
4401     if (p_verbose > 1)
4402     {
4403 	verbose_enter();
4404 	smsg((char_u *)_("finished sourcing %s"), fname);
4405 	if (sourcing_name != NULL)
4406 	    smsg((char_u *)_("continuing in %s"), sourcing_name);
4407 	verbose_leave();
4408     }
4409 #ifdef STARTUPTIME
4410     if (time_fd != NULL)
4411     {
4412 	vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
4413 	time_msg((char *)IObuff, &tv_start);
4414 	time_pop(&tv_rel);
4415     }
4416 #endif
4417 
4418 #ifdef FEAT_EVAL
4419     /*
4420      * After a "finish" in debug mode, need to break at first command of next
4421      * sourced file.
4422      */
4423     if (save_debug_break_level > ex_nesting_level
4424 	    && debug_break_level == ex_nesting_level)
4425 	++debug_break_level;
4426 #endif
4427 
4428 #ifdef FEAT_EVAL
4429 almosttheend:
4430     current_SID = save_current_SID;
4431     restore_funccal(save_funccalp);
4432 # ifdef FEAT_PROFILE
4433     if (do_profiling == PROF_YES)
4434 	prof_child_exit(&wait_start);		/* leaving a child now */
4435 # endif
4436 #endif
4437     fclose(cookie.fp);
4438     vim_free(cookie.nextline);
4439     vim_free(firstline);
4440 #ifdef FEAT_MBYTE
4441     convert_setup(&cookie.conv, NULL, NULL);
4442 #endif
4443 
4444 theend:
4445     vim_free(fname_exp);
4446     return retval;
4447 }
4448 
4449 #if defined(FEAT_EVAL) || defined(PROTO)
4450 
4451 /*
4452  * ":scriptnames"
4453  */
4454     void
4455 ex_scriptnames(exarg_T *eap UNUSED)
4456 {
4457     int i;
4458 
4459     for (i = 1; i <= script_items.ga_len && !got_int; ++i)
4460 	if (SCRIPT_ITEM(i).sn_name != NULL)
4461 	{
4462 	    home_replace(NULL, SCRIPT_ITEM(i).sn_name,
4463 						    NameBuff, MAXPATHL, TRUE);
4464 	    smsg((char_u *)"%3d: %s", i, NameBuff);
4465 	}
4466 }
4467 
4468 # if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
4469 /*
4470  * Fix slashes in the list of script names for 'shellslash'.
4471  */
4472     void
4473 scriptnames_slash_adjust(void)
4474 {
4475     int i;
4476 
4477     for (i = 1; i <= script_items.ga_len; ++i)
4478 	if (SCRIPT_ITEM(i).sn_name != NULL)
4479 	    slash_adjust(SCRIPT_ITEM(i).sn_name);
4480 }
4481 # endif
4482 
4483 /*
4484  * Get a pointer to a script name.  Used for ":verbose set".
4485  */
4486     char_u *
4487 get_scriptname(scid_T id)
4488 {
4489     if (id == SID_MODELINE)
4490 	return (char_u *)_("modeline");
4491     if (id == SID_CMDARG)
4492 	return (char_u *)_("--cmd argument");
4493     if (id == SID_CARG)
4494 	return (char_u *)_("-c argument");
4495     if (id == SID_ENV)
4496 	return (char_u *)_("environment variable");
4497     if (id == SID_ERROR)
4498 	return (char_u *)_("error handler");
4499     return SCRIPT_ITEM(id).sn_name;
4500 }
4501 
4502 # if defined(EXITFREE) || defined(PROTO)
4503     void
4504 free_scriptnames(void)
4505 {
4506     int			i;
4507 
4508     for (i = script_items.ga_len; i > 0; --i)
4509 	vim_free(SCRIPT_ITEM(i).sn_name);
4510     ga_clear(&script_items);
4511 }
4512 # endif
4513 
4514 #endif
4515 
4516 #if defined(USE_CR) || defined(PROTO)
4517 
4518 # if defined(__MSL__) && (__MSL__ >= 22)
4519 /*
4520  * Newer version of the Metrowerks library handle DOS and UNIX files
4521  * without help.
4522  * Test with earlier versions, MSL 2.2 is the library supplied with
4523  * Codewarrior Pro 2.
4524  */
4525     char *
4526 fgets_cr(char *s, int n, FILE *stream)
4527 {
4528     return fgets(s, n, stream);
4529 }
4530 # else
4531 /*
4532  * Version of fgets() which also works for lines ending in a <CR> only
4533  * (Macintosh format).
4534  * For older versions of the Metrowerks library.
4535  * At least CodeWarrior 9 needed this code.
4536  */
4537     char *
4538 fgets_cr(char *s, int n, FILE *stream)
4539 {
4540     int	c = 0;
4541     int char_read = 0;
4542 
4543     while (!feof(stream) && c != '\r' && c != '\n' && char_read < n - 1)
4544     {
4545 	c = fgetc(stream);
4546 	s[char_read++] = c;
4547 	/* If the file is in DOS format, we need to skip a NL after a CR.  I
4548 	 * thought it was the other way around, but this appears to work... */
4549 	if (c == '\n')
4550 	{
4551 	    c = fgetc(stream);
4552 	    if (c != '\r')
4553 		ungetc(c, stream);
4554 	}
4555     }
4556 
4557     s[char_read] = 0;
4558     if (char_read == 0)
4559 	return NULL;
4560 
4561     if (feof(stream) && char_read == 1)
4562 	return NULL;
4563 
4564     return s;
4565 }
4566 # endif
4567 #endif
4568 
4569 /*
4570  * Get one full line from a sourced file.
4571  * Called by do_cmdline() when it's called from do_source().
4572  *
4573  * Return a pointer to the line in allocated memory.
4574  * Return NULL for end-of-file or some error.
4575  */
4576     char_u *
4577 getsourceline(int c UNUSED, void *cookie, int indent UNUSED)
4578 {
4579     struct source_cookie *sp = (struct source_cookie *)cookie;
4580     char_u		*line;
4581     char_u		*p;
4582 
4583 #ifdef FEAT_EVAL
4584     /* If breakpoints have been added/deleted need to check for it. */
4585     if (sp->dbg_tick < debug_tick)
4586     {
4587 	sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
4588 	sp->dbg_tick = debug_tick;
4589     }
4590 # ifdef FEAT_PROFILE
4591     if (do_profiling == PROF_YES)
4592 	script_line_end();
4593 # endif
4594 #endif
4595     /*
4596      * Get current line.  If there is a read-ahead line, use it, otherwise get
4597      * one now.
4598      */
4599     if (sp->finished)
4600 	line = NULL;
4601     else if (sp->nextline == NULL)
4602 	line = get_one_sourceline(sp);
4603     else
4604     {
4605 	line = sp->nextline;
4606 	sp->nextline = NULL;
4607 	++sourcing_lnum;
4608     }
4609 #ifdef FEAT_PROFILE
4610     if (line != NULL && do_profiling == PROF_YES)
4611 	script_line_start();
4612 #endif
4613 
4614     /* Only concatenate lines starting with a \ when 'cpoptions' doesn't
4615      * contain the 'C' flag. */
4616     if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL))
4617     {
4618 	/* compensate for the one line read-ahead */
4619 	--sourcing_lnum;
4620 
4621 	/* Get the next line and concatenate it when it starts with a
4622 	 * backslash. We always need to read the next line, keep it in
4623 	 * sp->nextline. */
4624 	sp->nextline = get_one_sourceline(sp);
4625 	if (sp->nextline != NULL && *(p = skipwhite(sp->nextline)) == '\\')
4626 	{
4627 	    garray_T    ga;
4628 
4629 	    ga_init2(&ga, (int)sizeof(char_u), 400);
4630 	    ga_concat(&ga, line);
4631 	    ga_concat(&ga, p + 1);
4632 	    for (;;)
4633 	    {
4634 		vim_free(sp->nextline);
4635 		sp->nextline = get_one_sourceline(sp);
4636 		if (sp->nextline == NULL)
4637 		    break;
4638 		p = skipwhite(sp->nextline);
4639 		if (*p != '\\')
4640 		    break;
4641 		/* Adjust the growsize to the current length to speed up
4642 		 * concatenating many lines. */
4643 		if (ga.ga_len > 400)
4644 		{
4645 		    if (ga.ga_len > 8000)
4646 			ga.ga_growsize = 8000;
4647 		    else
4648 			ga.ga_growsize = ga.ga_len;
4649 		}
4650 		ga_concat(&ga, p + 1);
4651 	    }
4652 	    ga_append(&ga, NUL);
4653 	    vim_free(line);
4654 	    line = ga.ga_data;
4655 	}
4656     }
4657 
4658 #ifdef FEAT_MBYTE
4659     if (line != NULL && sp->conv.vc_type != CONV_NONE)
4660     {
4661 	char_u	*s;
4662 
4663 	/* Convert the encoding of the script line. */
4664 	s = string_convert(&sp->conv, line, NULL);
4665 	if (s != NULL)
4666 	{
4667 	    vim_free(line);
4668 	    line = s;
4669 	}
4670     }
4671 #endif
4672 
4673 #ifdef FEAT_EVAL
4674     /* Did we encounter a breakpoint? */
4675     if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
4676     {
4677 	dbg_breakpoint(sp->fname, sourcing_lnum);
4678 	/* Find next breakpoint. */
4679 	sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
4680 	sp->dbg_tick = debug_tick;
4681     }
4682 #endif
4683 
4684     return line;
4685 }
4686 
4687     static char_u *
4688 get_one_sourceline(struct source_cookie *sp)
4689 {
4690     garray_T		ga;
4691     int			len;
4692     int			c;
4693     char_u		*buf;
4694 #ifdef USE_CRNL
4695     int			has_cr;		/* CR-LF found */
4696 #endif
4697 #ifdef USE_CR
4698     char_u		*scan;
4699 #endif
4700     int			have_read = FALSE;
4701 
4702     /* use a growarray to store the sourced line */
4703     ga_init2(&ga, 1, 250);
4704 
4705     /*
4706      * Loop until there is a finished line (or end-of-file).
4707      */
4708     sourcing_lnum++;
4709     for (;;)
4710     {
4711 	/* make room to read at least 120 (more) characters */
4712 	if (ga_grow(&ga, 120) == FAIL)
4713 	    break;
4714 	buf = (char_u *)ga.ga_data;
4715 
4716 #ifdef USE_CR
4717 	if (sp->fileformat == EOL_MAC)
4718 	{
4719 	    if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
4720 							      sp->fp) == NULL)
4721 		break;
4722 	}
4723 	else
4724 #endif
4725 	    if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
4726 							      sp->fp) == NULL)
4727 		break;
4728 	len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
4729 #ifdef USE_CRNL
4730 	/* Ignore a trailing CTRL-Z, when in Dos mode.	Only recognize the
4731 	 * CTRL-Z by its own, or after a NL. */
4732 	if (	   (len == 1 || (len >= 2 && buf[len - 2] == '\n'))
4733 		&& sp->fileformat == EOL_DOS
4734 		&& buf[len - 1] == Ctrl_Z)
4735 	{
4736 	    buf[len - 1] = NUL;
4737 	    break;
4738 	}
4739 #endif
4740 
4741 #ifdef USE_CR
4742 	/* If the read doesn't stop on a new line, and there's
4743 	 * some CR then we assume a Mac format */
4744 	if (sp->fileformat == EOL_UNKNOWN)
4745 	{
4746 	    if (buf[len - 1] != '\n' && vim_strchr(buf, '\r') != NULL)
4747 		sp->fileformat = EOL_MAC;
4748 	    else
4749 		sp->fileformat = EOL_UNIX;
4750 	}
4751 
4752 	if (sp->fileformat == EOL_MAC)
4753 	{
4754 	    scan = vim_strchr(buf, '\r');
4755 
4756 	    if (scan != NULL)
4757 	    {
4758 		*scan = '\n';
4759 		if (*(scan + 1) != 0)
4760 		{
4761 		    *(scan + 1) = 0;
4762 		    fseek(sp->fp, (long)(scan - buf - len + 1), SEEK_CUR);
4763 		}
4764 	    }
4765 	    len = STRLEN(buf);
4766 	}
4767 #endif
4768 
4769 	have_read = TRUE;
4770 	ga.ga_len = len;
4771 
4772 	/* If the line was longer than the buffer, read more. */
4773 	if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
4774 	    continue;
4775 
4776 	if (len >= 1 && buf[len - 1] == '\n')	/* remove trailing NL */
4777 	{
4778 #ifdef USE_CRNL
4779 	    has_cr = (len >= 2 && buf[len - 2] == '\r');
4780 	    if (sp->fileformat == EOL_UNKNOWN)
4781 	    {
4782 		if (has_cr)
4783 		    sp->fileformat = EOL_DOS;
4784 		else
4785 		    sp->fileformat = EOL_UNIX;
4786 	    }
4787 
4788 	    if (sp->fileformat == EOL_DOS)
4789 	    {
4790 		if (has_cr)	    /* replace trailing CR */
4791 		{
4792 		    buf[len - 2] = '\n';
4793 		    --len;
4794 		    --ga.ga_len;
4795 		}
4796 		else	    /* lines like ":map xx yy^M" will have failed */
4797 		{
4798 		    if (!sp->error)
4799 		    {
4800 			msg_source(HL_ATTR(HLF_W));
4801 			EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
4802 		    }
4803 		    sp->error = TRUE;
4804 		    sp->fileformat = EOL_UNIX;
4805 		}
4806 	    }
4807 #endif
4808 	    /* The '\n' is escaped if there is an odd number of ^V's just
4809 	     * before it, first set "c" just before the 'V's and then check
4810 	     * len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo */
4811 	    for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--)
4812 		;
4813 	    if ((len & 1) != (c & 1))	/* escaped NL, read more */
4814 	    {
4815 		sourcing_lnum++;
4816 		continue;
4817 	    }
4818 
4819 	    buf[len - 1] = NUL;		/* remove the NL */
4820 	}
4821 
4822 	/*
4823 	 * Check for ^C here now and then, so recursive :so can be broken.
4824 	 */
4825 	line_breakcheck();
4826 	break;
4827     }
4828 
4829     if (have_read)
4830 	return (char_u *)ga.ga_data;
4831 
4832     vim_free(ga.ga_data);
4833     return NULL;
4834 }
4835 
4836 #if defined(FEAT_PROFILE) || defined(PROTO)
4837 /*
4838  * Called when starting to read a script line.
4839  * "sourcing_lnum" must be correct!
4840  * When skipping lines it may not actually be executed, but we won't find out
4841  * until later and we need to store the time now.
4842  */
4843     void
4844 script_line_start(void)
4845 {
4846     scriptitem_T    *si;
4847     sn_prl_T	    *pp;
4848 
4849     if (current_SID <= 0 || current_SID > script_items.ga_len)
4850 	return;
4851     si = &SCRIPT_ITEM(current_SID);
4852     if (si->sn_prof_on && sourcing_lnum >= 1)
4853     {
4854 	/* Grow the array before starting the timer, so that the time spent
4855 	 * here isn't counted. */
4856 	(void)ga_grow(&si->sn_prl_ga, (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
4857 	si->sn_prl_idx = sourcing_lnum - 1;
4858 	while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
4859 		&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
4860 	{
4861 	    /* Zero counters for a line that was not used before. */
4862 	    pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len);
4863 	    pp->snp_count = 0;
4864 	    profile_zero(&pp->sn_prl_total);
4865 	    profile_zero(&pp->sn_prl_self);
4866 	    ++si->sn_prl_ga.ga_len;
4867 	}
4868 	si->sn_prl_execed = FALSE;
4869 	profile_start(&si->sn_prl_start);
4870 	profile_zero(&si->sn_prl_children);
4871 	profile_get_wait(&si->sn_prl_wait);
4872     }
4873 }
4874 
4875 /*
4876  * Called when actually executing a function line.
4877  */
4878     void
4879 script_line_exec(void)
4880 {
4881     scriptitem_T    *si;
4882 
4883     if (current_SID <= 0 || current_SID > script_items.ga_len)
4884 	return;
4885     si = &SCRIPT_ITEM(current_SID);
4886     if (si->sn_prof_on && si->sn_prl_idx >= 0)
4887 	si->sn_prl_execed = TRUE;
4888 }
4889 
4890 /*
4891  * Called when done with a function line.
4892  */
4893     void
4894 script_line_end(void)
4895 {
4896     scriptitem_T    *si;
4897     sn_prl_T	    *pp;
4898 
4899     if (current_SID <= 0 || current_SID > script_items.ga_len)
4900 	return;
4901     si = &SCRIPT_ITEM(current_SID);
4902     if (si->sn_prof_on && si->sn_prl_idx >= 0
4903 				     && si->sn_prl_idx < si->sn_prl_ga.ga_len)
4904     {
4905 	if (si->sn_prl_execed)
4906 	{
4907 	    pp = &PRL_ITEM(si, si->sn_prl_idx);
4908 	    ++pp->snp_count;
4909 	    profile_end(&si->sn_prl_start);
4910 	    profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start);
4911 	    profile_add(&pp->sn_prl_total, &si->sn_prl_start);
4912 	    profile_self(&pp->sn_prl_self, &si->sn_prl_start,
4913 							&si->sn_prl_children);
4914 	}
4915 	si->sn_prl_idx = -1;
4916     }
4917 }
4918 #endif
4919 
4920 /*
4921  * ":scriptencoding": Set encoding conversion for a sourced script.
4922  * Without the multi-byte feature it's simply ignored.
4923  */
4924     void
4925 ex_scriptencoding(exarg_T *eap UNUSED)
4926 {
4927 #ifdef FEAT_MBYTE
4928     struct source_cookie	*sp;
4929     char_u			*name;
4930 
4931     if (!getline_equal(eap->getline, eap->cookie, getsourceline))
4932     {
4933 	EMSG(_("E167: :scriptencoding used outside of a sourced file"));
4934 	return;
4935     }
4936 
4937     if (*eap->arg != NUL)
4938     {
4939 	name = enc_canonize(eap->arg);
4940 	if (name == NULL)	/* out of memory */
4941 	    return;
4942     }
4943     else
4944 	name = eap->arg;
4945 
4946     /* Setup for conversion from the specified encoding to 'encoding'. */
4947     sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie);
4948     convert_setup(&sp->conv, name, p_enc);
4949 
4950     if (name != eap->arg)
4951 	vim_free(name);
4952 #endif
4953 }
4954 
4955 #if defined(FEAT_EVAL) || defined(PROTO)
4956 /*
4957  * ":finish": Mark a sourced file as finished.
4958  */
4959     void
4960 ex_finish(exarg_T *eap)
4961 {
4962     if (getline_equal(eap->getline, eap->cookie, getsourceline))
4963 	do_finish(eap, FALSE);
4964     else
4965 	EMSG(_("E168: :finish used outside of a sourced file"));
4966 }
4967 
4968 /*
4969  * Mark a sourced file as finished.  Possibly makes the ":finish" pending.
4970  * Also called for a pending finish at the ":endtry" or after returning from
4971  * an extra do_cmdline().  "reanimate" is used in the latter case.
4972  */
4973     void
4974 do_finish(exarg_T *eap, int reanimate)
4975 {
4976     int		idx;
4977 
4978     if (reanimate)
4979 	((struct source_cookie *)getline_cookie(eap->getline,
4980 					      eap->cookie))->finished = FALSE;
4981 
4982     /*
4983      * Cleanup (and inactivate) conditionals, but stop when a try conditional
4984      * not in its finally clause (which then is to be executed next) is found.
4985      * In this case, make the ":finish" pending for execution at the ":endtry".
4986      * Otherwise, finish normally.
4987      */
4988     idx = cleanup_conditionals(eap->cstack, 0, TRUE);
4989     if (idx >= 0)
4990     {
4991 	eap->cstack->cs_pending[idx] = CSTP_FINISH;
4992 	report_make_pending(CSTP_FINISH, NULL);
4993     }
4994     else
4995 	((struct source_cookie *)getline_cookie(eap->getline,
4996 					       eap->cookie))->finished = TRUE;
4997 }
4998 
4999 
5000 /*
5001  * Return TRUE when a sourced file had the ":finish" command: Don't give error
5002  * message for missing ":endif".
5003  * Return FALSE when not sourcing a file.
5004  */
5005     int
5006 source_finished(
5007     char_u	*(*fgetline)(int, void *, int),
5008     void	*cookie)
5009 {
5010     return (getline_equal(fgetline, cookie, getsourceline)
5011 	    && ((struct source_cookie *)getline_cookie(
5012 						fgetline, cookie))->finished);
5013 }
5014 #endif
5015 
5016 #if defined(FEAT_LISTCMDS) || defined(PROTO)
5017 /*
5018  * ":checktime [buffer]"
5019  */
5020     void
5021 ex_checktime(exarg_T *eap)
5022 {
5023     buf_T	*buf;
5024     int		save_no_check_timestamps = no_check_timestamps;
5025 
5026     no_check_timestamps = 0;
5027     if (eap->addr_count == 0)	/* default is all buffers */
5028 	check_timestamps(FALSE);
5029     else
5030     {
5031 	buf = buflist_findnr((int)eap->line2);
5032 	if (buf != NULL)	/* cannot happen? */
5033 	    (void)buf_check_timestamp(buf, FALSE);
5034     }
5035     no_check_timestamps = save_no_check_timestamps;
5036 }
5037 #endif
5038 
5039 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
5040 	&& (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG))
5041 # define HAVE_GET_LOCALE_VAL
5042 static char_u *get_locale_val(int what);
5043 
5044     static char_u *
5045 get_locale_val(int what)
5046 {
5047     char_u	*loc;
5048 
5049     /* Obtain the locale value from the libraries. */
5050     loc = (char_u *)setlocale(what, NULL);
5051 
5052 # ifdef WIN32
5053     if (loc != NULL)
5054     {
5055 	char_u	*p;
5056 
5057 	/* setocale() returns something like "LC_COLLATE=<name>;LC_..." when
5058 	 * one of the values (e.g., LC_CTYPE) differs. */
5059 	p = vim_strchr(loc, '=');
5060 	if (p != NULL)
5061 	{
5062 	    loc = ++p;
5063 	    while (*p != NUL)	/* remove trailing newline */
5064 	    {
5065 		if (*p < ' ' || *p == ';')
5066 		{
5067 		    *p = NUL;
5068 		    break;
5069 		}
5070 		++p;
5071 	    }
5072 	}
5073     }
5074 # endif
5075 
5076     return loc;
5077 }
5078 #endif
5079 
5080 
5081 #ifdef WIN32
5082 /*
5083  * On MS-Windows locale names are strings like "German_Germany.1252", but
5084  * gettext expects "de".  Try to translate one into another here for a few
5085  * supported languages.
5086  */
5087     static char_u *
5088 gettext_lang(char_u *name)
5089 {
5090     int		i;
5091     static char *(mtable[]) = {
5092 			"afrikaans",	"af",
5093 			"czech",	"cs",
5094 			"dutch",	"nl",
5095 			"german",	"de",
5096 			"english_united kingdom", "en_GB",
5097 			"spanish",	"es",
5098 			"french",	"fr",
5099 			"italian",	"it",
5100 			"japanese",	"ja",
5101 			"korean",	"ko",
5102 			"norwegian",	"no",
5103 			"polish",	"pl",
5104 			"russian",	"ru",
5105 			"slovak",	"sk",
5106 			"swedish",	"sv",
5107 			"ukrainian",	"uk",
5108 			"chinese_china", "zh_CN",
5109 			"chinese_taiwan", "zh_TW",
5110 			NULL};
5111 
5112     for (i = 0; mtable[i] != NULL; i += 2)
5113 	if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0)
5114 	    return (char_u *)mtable[i + 1];
5115     return name;
5116 }
5117 #endif
5118 
5119 #if defined(FEAT_MULTI_LANG) || defined(PROTO)
5120 /*
5121  * Obtain the current messages language.  Used to set the default for
5122  * 'helplang'.  May return NULL or an empty string.
5123  */
5124     char_u *
5125 get_mess_lang(void)
5126 {
5127     char_u *p;
5128 
5129 # ifdef HAVE_GET_LOCALE_VAL
5130 #  if defined(LC_MESSAGES)
5131     p = get_locale_val(LC_MESSAGES);
5132 #  else
5133     /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
5134      * may be set to the LCID number.  LC_COLLATE is the best guess, LC_TIME
5135      * and LC_MONETARY may be set differently for a Japanese working in the
5136      * US. */
5137     p = get_locale_val(LC_COLLATE);
5138 #  endif
5139 # else
5140     p = mch_getenv((char_u *)"LC_ALL");
5141     if (p == NULL || *p == NUL)
5142     {
5143 	p = mch_getenv((char_u *)"LC_MESSAGES");
5144 	if (p == NULL || *p == NUL)
5145 	    p = mch_getenv((char_u *)"LANG");
5146     }
5147 # endif
5148 # ifdef WIN32
5149     p = gettext_lang(p);
5150 # endif
5151     return p;
5152 }
5153 #endif
5154 
5155 /* Complicated #if; matches with where get_mess_env() is used below. */
5156 #if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
5157 	    && defined(LC_MESSAGES))) \
5158 	|| ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
5159 		&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) \
5160 		&& !defined(LC_MESSAGES))
5161 static char_u *get_mess_env(void);
5162 
5163 /*
5164  * Get the language used for messages from the environment.
5165  */
5166     static char_u *
5167 get_mess_env(void)
5168 {
5169     char_u	*p;
5170 
5171     p = mch_getenv((char_u *)"LC_ALL");
5172     if (p == NULL || *p == NUL)
5173     {
5174 	p = mch_getenv((char_u *)"LC_MESSAGES");
5175 	if (p == NULL || *p == NUL)
5176 	{
5177 	    p = mch_getenv((char_u *)"LANG");
5178 	    if (p != NULL && VIM_ISDIGIT(*p))
5179 		p = NULL;		/* ignore something like "1043" */
5180 # ifdef HAVE_GET_LOCALE_VAL
5181 	    if (p == NULL || *p == NUL)
5182 		p = get_locale_val(LC_CTYPE);
5183 # endif
5184 	}
5185     }
5186     return p;
5187 }
5188 #endif
5189 
5190 #if defined(FEAT_EVAL) || defined(PROTO)
5191 
5192 /*
5193  * Set the "v:lang" variable according to the current locale setting.
5194  * Also do "v:lc_time"and "v:ctype".
5195  */
5196     void
5197 set_lang_var(void)
5198 {
5199     char_u	*loc;
5200 
5201 # ifdef HAVE_GET_LOCALE_VAL
5202     loc = get_locale_val(LC_CTYPE);
5203 # else
5204     /* setlocale() not supported: use the default value */
5205     loc = (char_u *)"C";
5206 # endif
5207     set_vim_var_string(VV_CTYPE, loc, -1);
5208 
5209     /* When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
5210      * back to LC_CTYPE if it's empty. */
5211 # if defined(HAVE_GET_LOCALE_VAL) && defined(LC_MESSAGES)
5212     loc = get_locale_val(LC_MESSAGES);
5213 # else
5214     loc = get_mess_env();
5215 # endif
5216     set_vim_var_string(VV_LANG, loc, -1);
5217 
5218 # ifdef HAVE_GET_LOCALE_VAL
5219     loc = get_locale_val(LC_TIME);
5220 # endif
5221     set_vim_var_string(VV_LC_TIME, loc, -1);
5222 }
5223 #endif
5224 
5225 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
5226 	&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
5227 /*
5228  * ":language":  Set the language (locale).
5229  */
5230     void
5231 ex_language(exarg_T *eap)
5232 {
5233     char	*loc;
5234     char_u	*p;
5235     char_u	*name;
5236     int		what = LC_ALL;
5237     char	*whatstr = "";
5238 #ifdef LC_MESSAGES
5239 # define VIM_LC_MESSAGES LC_MESSAGES
5240 #else
5241 # define VIM_LC_MESSAGES 6789
5242 #endif
5243 
5244     name = eap->arg;
5245 
5246     /* Check for "messages {name}", "ctype {name}" or "time {name}" argument.
5247      * Allow abbreviation, but require at least 3 characters to avoid
5248      * confusion with a two letter language name "me" or "ct". */
5249     p = skiptowhite(eap->arg);
5250     if ((*p == NUL || VIM_ISWHITE(*p)) && p - eap->arg >= 3)
5251     {
5252 	if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0)
5253 	{
5254 	    what = VIM_LC_MESSAGES;
5255 	    name = skipwhite(p);
5256 	    whatstr = "messages ";
5257 	}
5258 	else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0)
5259 	{
5260 	    what = LC_CTYPE;
5261 	    name = skipwhite(p);
5262 	    whatstr = "ctype ";
5263 	}
5264 	else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0)
5265 	{
5266 	    what = LC_TIME;
5267 	    name = skipwhite(p);
5268 	    whatstr = "time ";
5269 	}
5270     }
5271 
5272     if (*name == NUL)
5273     {
5274 #ifndef LC_MESSAGES
5275 	if (what == VIM_LC_MESSAGES)
5276 	    p = get_mess_env();
5277 	else
5278 #endif
5279 	    p = (char_u *)setlocale(what, NULL);
5280 	if (p == NULL || *p == NUL)
5281 	    p = (char_u *)"Unknown";
5282 	smsg((char_u *)_("Current %slanguage: \"%s\""), whatstr, p);
5283     }
5284     else
5285     {
5286 #ifndef LC_MESSAGES
5287 	if (what == VIM_LC_MESSAGES)
5288 	    loc = "";
5289 	else
5290 #endif
5291 	{
5292 	    loc = setlocale(what, (char *)name);
5293 #if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
5294 	    /* Make sure strtod() uses a decimal point, not a comma. */
5295 	    setlocale(LC_NUMERIC, "C");
5296 #endif
5297 	}
5298 	if (loc == NULL)
5299 	    EMSG2(_("E197: Cannot set language to \"%s\""), name);
5300 	else
5301 	{
5302 #ifdef HAVE_NL_MSG_CAT_CNTR
5303 	    /* Need to do this for GNU gettext, otherwise cached translations
5304 	     * will be used again. */
5305 	    extern int _nl_msg_cat_cntr;
5306 
5307 	    ++_nl_msg_cat_cntr;
5308 #endif
5309 	    /* Reset $LC_ALL, otherwise it would overrule everything. */
5310 	    vim_setenv((char_u *)"LC_ALL", (char_u *)"");
5311 
5312 	    if (what != LC_TIME)
5313 	    {
5314 		/* Tell gettext() what to translate to.  It apparently doesn't
5315 		 * use the currently effective locale.  Also do this when
5316 		 * FEAT_GETTEXT isn't defined, so that shell commands use this
5317 		 * value. */
5318 		if (what == LC_ALL)
5319 		{
5320 		    vim_setenv((char_u *)"LANG", name);
5321 
5322 		    /* Clear $LANGUAGE because GNU gettext uses it. */
5323 		    vim_setenv((char_u *)"LANGUAGE", (char_u *)"");
5324 # ifdef WIN32
5325 		    /* Apparently MS-Windows printf() may cause a crash when
5326 		     * we give it 8-bit text while it's expecting text in the
5327 		     * current locale.  This call avoids that. */
5328 		    setlocale(LC_CTYPE, "C");
5329 # endif
5330 		}
5331 		if (what != LC_CTYPE)
5332 		{
5333 		    char_u	*mname;
5334 #ifdef WIN32
5335 		    mname = gettext_lang(name);
5336 #else
5337 		    mname = name;
5338 #endif
5339 		    vim_setenv((char_u *)"LC_MESSAGES", mname);
5340 #ifdef FEAT_MULTI_LANG
5341 		    set_helplang_default(mname);
5342 #endif
5343 		}
5344 	    }
5345 
5346 # ifdef FEAT_EVAL
5347 	    /* Set v:lang, v:lc_time and v:ctype to the final result. */
5348 	    set_lang_var();
5349 # endif
5350 # ifdef FEAT_TITLE
5351 	    maketitle();
5352 # endif
5353 	}
5354     }
5355 }
5356 
5357 # if defined(FEAT_CMDL_COMPL) || defined(PROTO)
5358 
5359 static char_u	**locales = NULL;	/* Array of all available locales */
5360 
5361 #  ifndef WIN32
5362 static int	did_init_locales = FALSE;
5363 
5364 /* Return an array of strings for all available locales + NULL for the
5365  * last element.  Return NULL in case of error. */
5366     static char_u **
5367 find_locales(void)
5368 {
5369     garray_T	locales_ga;
5370     char_u	*loc;
5371 
5372     /* Find all available locales by running command "locale -a".  If this
5373      * doesn't work we won't have completion. */
5374     char_u *locale_a = get_cmd_output((char_u *)"locale -a",
5375 						    NULL, SHELL_SILENT, NULL);
5376     if (locale_a == NULL)
5377 	return NULL;
5378     ga_init2(&locales_ga, sizeof(char_u *), 20);
5379 
5380     /* Transform locale_a string where each locale is separated by "\n"
5381      * into an array of locale strings. */
5382     loc = (char_u *)strtok((char *)locale_a, "\n");
5383 
5384     while (loc != NULL)
5385     {
5386 	if (ga_grow(&locales_ga, 1) == FAIL)
5387 	    break;
5388 	loc = vim_strsave(loc);
5389 	if (loc == NULL)
5390 	    break;
5391 
5392 	((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc;
5393 	loc = (char_u *)strtok(NULL, "\n");
5394     }
5395     vim_free(locale_a);
5396     if (ga_grow(&locales_ga, 1) == FAIL)
5397     {
5398 	ga_clear(&locales_ga);
5399 	return NULL;
5400     }
5401     ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
5402     return (char_u **)locales_ga.ga_data;
5403 }
5404 #  endif
5405 
5406 /*
5407  * Lazy initialization of all available locales.
5408  */
5409     static void
5410 init_locales(void)
5411 {
5412 #  ifndef WIN32
5413     if (!did_init_locales)
5414     {
5415 	did_init_locales = TRUE;
5416 	locales = find_locales();
5417     }
5418 #  endif
5419 }
5420 
5421 #  if defined(EXITFREE) || defined(PROTO)
5422     void
5423 free_locales(void)
5424 {
5425     int			i;
5426     if (locales != NULL)
5427     {
5428 	for (i = 0; locales[i] != NULL; i++)
5429 	    vim_free(locales[i]);
5430 	vim_free(locales);
5431 	locales = NULL;
5432     }
5433 }
5434 #  endif
5435 
5436 /*
5437  * Function given to ExpandGeneric() to obtain the possible arguments of the
5438  * ":language" command.
5439  */
5440     char_u *
5441 get_lang_arg(expand_T *xp UNUSED, int idx)
5442 {
5443     if (idx == 0)
5444 	return (char_u *)"messages";
5445     if (idx == 1)
5446 	return (char_u *)"ctype";
5447     if (idx == 2)
5448 	return (char_u *)"time";
5449 
5450     init_locales();
5451     if (locales == NULL)
5452 	return NULL;
5453     return locales[idx - 3];
5454 }
5455 
5456 /*
5457  * Function given to ExpandGeneric() to obtain the available locales.
5458  */
5459     char_u *
5460 get_locales(expand_T *xp UNUSED, int idx)
5461 {
5462     init_locales();
5463     if (locales == NULL)
5464 	return NULL;
5465     return locales[idx];
5466 }
5467 # endif
5468 
5469 #endif
5470