xref: /vim-8.2.3635/src/ex_cmds2.c (revision b2a76ec0)
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 (	   P_HID(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 (EMSG2(_("E162: No write since last change for buffer \"%s\""),
2184 		    buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname))
2185 	{
2186 	    save = no_wait_return;
2187 	    no_wait_return = FALSE;
2188 	    wait_return(FALSE);
2189 	    no_wait_return = save;
2190 	}
2191     }
2192 
2193 #ifdef FEAT_WINDOWS
2194     /* Try to find a window that contains the buffer. */
2195     if (buf != curbuf)
2196 	FOR_ALL_TAB_WINDOWS(tp, wp)
2197 	    if (wp->w_buffer == buf)
2198 	    {
2199 # ifdef FEAT_AUTOCMD
2200 		bufref_T bufref;
2201 
2202 		set_bufref(&bufref, buf);
2203 # endif
2204 		goto_tabpage_win(tp, wp);
2205 # ifdef FEAT_AUTOCMD
2206 		/* Paranoia: did autocms wipe out the buffer with changes? */
2207 		if (!bufref_valid(&bufref))
2208 		{
2209 		    goto theend;
2210 		}
2211 # endif
2212 		goto buf_found;
2213 	    }
2214 buf_found:
2215 #endif
2216 
2217     /* Open the changed buffer in the current window. */
2218     if (buf != curbuf)
2219 	set_curbuf(buf, unload ? DOBUF_UNLOAD : DOBUF_GOTO);
2220 
2221 theend:
2222     vim_free(bufnrs);
2223     return ret;
2224 }
2225 
2226 /*
2227  * return FAIL if there is no file name, OK if there is one
2228  * give error message for FAIL
2229  */
2230     int
2231 check_fname(void)
2232 {
2233     if (curbuf->b_ffname == NULL)
2234     {
2235 	EMSG(_(e_noname));
2236 	return FAIL;
2237     }
2238     return OK;
2239 }
2240 
2241 /*
2242  * flush the contents of a buffer, unless it has no file name
2243  *
2244  * return FAIL for failure, OK otherwise
2245  */
2246     int
2247 buf_write_all(buf_T *buf, int forceit)
2248 {
2249     int	    retval;
2250 #ifdef FEAT_AUTOCMD
2251     buf_T	*old_curbuf = curbuf;
2252 #endif
2253 
2254     retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
2255 				   (linenr_T)1, buf->b_ml.ml_line_count, NULL,
2256 						  FALSE, forceit, TRUE, FALSE));
2257 #ifdef FEAT_AUTOCMD
2258     if (curbuf != old_curbuf)
2259     {
2260 	msg_source(HL_ATTR(HLF_W));
2261 	MSG(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
2262     }
2263 #endif
2264     return retval;
2265 }
2266 
2267 /*
2268  * Code to handle the argument list.
2269  */
2270 
2271 static char_u	*do_one_arg(char_u *str);
2272 static int	do_arglist(char_u *str, int what, int after);
2273 static void	alist_check_arg_idx(void);
2274 static int	editing_arg_idx(win_T *win);
2275 #ifdef FEAT_LISTCMDS
2276 static int	alist_add_list(int count, char_u **files, int after);
2277 #endif
2278 #define AL_SET	1
2279 #define AL_ADD	2
2280 #define AL_DEL	3
2281 
2282 /*
2283  * Isolate one argument, taking backticks.
2284  * Changes the argument in-place, puts a NUL after it.  Backticks remain.
2285  * Return a pointer to the start of the next argument.
2286  */
2287     static char_u *
2288 do_one_arg(char_u *str)
2289 {
2290     char_u	*p;
2291     int		inbacktick;
2292 
2293     inbacktick = FALSE;
2294     for (p = str; *str; ++str)
2295     {
2296 	/* When the backslash is used for escaping the special meaning of a
2297 	 * character we need to keep it until wildcard expansion. */
2298 	if (rem_backslash(str))
2299 	{
2300 	    *p++ = *str++;
2301 	    *p++ = *str;
2302 	}
2303 	else
2304 	{
2305 	    /* An item ends at a space not in backticks */
2306 	    if (!inbacktick && vim_isspace(*str))
2307 		break;
2308 	    if (*str == '`')
2309 		inbacktick ^= TRUE;
2310 	    *p++ = *str;
2311 	}
2312     }
2313     str = skipwhite(str);
2314     *p = NUL;
2315 
2316     return str;
2317 }
2318 
2319 /*
2320  * Separate the arguments in "str" and return a list of pointers in the
2321  * growarray "gap".
2322  */
2323     int
2324 get_arglist(garray_T *gap, char_u *str)
2325 {
2326     ga_init2(gap, (int)sizeof(char_u *), 20);
2327     while (*str != NUL)
2328     {
2329 	if (ga_grow(gap, 1) == FAIL)
2330 	{
2331 	    ga_clear(gap);
2332 	    return FAIL;
2333 	}
2334 	((char_u **)gap->ga_data)[gap->ga_len++] = str;
2335 
2336 	/* Isolate one argument, change it in-place, put a NUL after it. */
2337 	str = do_one_arg(str);
2338     }
2339     return OK;
2340 }
2341 
2342 #if defined(FEAT_QUICKFIX) || defined(FEAT_SYN_HL) || defined(PROTO)
2343 /*
2344  * Parse a list of arguments (file names), expand them and return in
2345  * "fnames[fcountp]".  When "wig" is TRUE, removes files matching 'wildignore'.
2346  * Return FAIL or OK.
2347  */
2348     int
2349 get_arglist_exp(
2350     char_u	*str,
2351     int		*fcountp,
2352     char_u	***fnamesp,
2353     int		wig)
2354 {
2355     garray_T	ga;
2356     int		i;
2357 
2358     if (get_arglist(&ga, str) == FAIL)
2359 	return FAIL;
2360     if (wig == TRUE)
2361 	i = expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
2362 					fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
2363     else
2364 	i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
2365 					fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
2366 
2367     ga_clear(&ga);
2368     return i;
2369 }
2370 #endif
2371 
2372 #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
2373 /*
2374  * Redefine the argument list.
2375  */
2376     void
2377 set_arglist(char_u *str)
2378 {
2379     do_arglist(str, AL_SET, 0);
2380 }
2381 #endif
2382 
2383 /*
2384  * "what" == AL_SET: Redefine the argument list to 'str'.
2385  * "what" == AL_ADD: add files in 'str' to the argument list after "after".
2386  * "what" == AL_DEL: remove files in 'str' from the argument list.
2387  *
2388  * Return FAIL for failure, OK otherwise.
2389  */
2390     static int
2391 do_arglist(
2392     char_u	*str,
2393     int		what,
2394     int		after UNUSED)		/* 0 means before first one */
2395 {
2396     garray_T	new_ga;
2397     int		exp_count;
2398     char_u	**exp_files;
2399     int		i;
2400 #ifdef FEAT_LISTCMDS
2401     char_u	*p;
2402     int		match;
2403 #endif
2404 
2405     /*
2406      * Set default argument for ":argadd" command.
2407      */
2408     if (what == AL_ADD && *str == NUL)
2409     {
2410 	if (curbuf->b_ffname == NULL)
2411 	    return FAIL;
2412 	str = curbuf->b_fname;
2413     }
2414 
2415     /*
2416      * Collect all file name arguments in "new_ga".
2417      */
2418     if (get_arglist(&new_ga, str) == FAIL)
2419 	return FAIL;
2420 
2421 #ifdef FEAT_LISTCMDS
2422     if (what == AL_DEL)
2423     {
2424 	regmatch_T	regmatch;
2425 	int		didone;
2426 
2427 	/*
2428 	 * Delete the items: use each item as a regexp and find a match in the
2429 	 * argument list.
2430 	 */
2431 	regmatch.rm_ic = p_fic;	/* ignore case when 'fileignorecase' is set */
2432 	for (i = 0; i < new_ga.ga_len && !got_int; ++i)
2433 	{
2434 	    p = ((char_u **)new_ga.ga_data)[i];
2435 	    p = file_pat_to_reg_pat(p, NULL, NULL, FALSE);
2436 	    if (p == NULL)
2437 		break;
2438 	    regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
2439 	    if (regmatch.regprog == NULL)
2440 	    {
2441 		vim_free(p);
2442 		break;
2443 	    }
2444 
2445 	    didone = FALSE;
2446 	    for (match = 0; match < ARGCOUNT; ++match)
2447 		if (vim_regexec(&regmatch, alist_name(&ARGLIST[match]),
2448 								  (colnr_T)0))
2449 		{
2450 		    didone = TRUE;
2451 		    vim_free(ARGLIST[match].ae_fname);
2452 		    mch_memmove(ARGLIST + match, ARGLIST + match + 1,
2453 			    (ARGCOUNT - match - 1) * sizeof(aentry_T));
2454 		    --ALIST(curwin)->al_ga.ga_len;
2455 		    if (curwin->w_arg_idx > match)
2456 			--curwin->w_arg_idx;
2457 		    --match;
2458 		}
2459 
2460 	    vim_regfree(regmatch.regprog);
2461 	    vim_free(p);
2462 	    if (!didone)
2463 		EMSG2(_(e_nomatch2), ((char_u **)new_ga.ga_data)[i]);
2464 	}
2465 	ga_clear(&new_ga);
2466     }
2467     else
2468 #endif
2469     {
2470 	i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
2471 		&exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND);
2472 	ga_clear(&new_ga);
2473 	if (i == FAIL || exp_count == 0)
2474 	{
2475 	    EMSG(_(e_nomatch));
2476 	    return FAIL;
2477 	}
2478 
2479 #ifdef FEAT_LISTCMDS
2480 	if (what == AL_ADD)
2481 	{
2482 	    (void)alist_add_list(exp_count, exp_files, after);
2483 	    vim_free(exp_files);
2484 	}
2485 	else /* what == AL_SET */
2486 #endif
2487 	    alist_set(ALIST(curwin), exp_count, exp_files, FALSE, NULL, 0);
2488     }
2489 
2490     alist_check_arg_idx();
2491 
2492     return OK;
2493 }
2494 
2495 /*
2496  * Check the validity of the arg_idx for each other window.
2497  */
2498     static void
2499 alist_check_arg_idx(void)
2500 {
2501 #ifdef FEAT_WINDOWS
2502     win_T	*win;
2503     tabpage_T	*tp;
2504 
2505     FOR_ALL_TAB_WINDOWS(tp, win)
2506 	if (win->w_alist == curwin->w_alist)
2507 	    check_arg_idx(win);
2508 #else
2509     check_arg_idx(curwin);
2510 #endif
2511 }
2512 
2513 /*
2514  * Return TRUE if window "win" is editing the file at the current argument
2515  * index.
2516  */
2517     static int
2518 editing_arg_idx(win_T *win)
2519 {
2520     return !(win->w_arg_idx >= WARGCOUNT(win)
2521 		|| (win->w_buffer->b_fnum
2522 				      != WARGLIST(win)[win->w_arg_idx].ae_fnum
2523 		    && (win->w_buffer->b_ffname == NULL
2524 			 || !(fullpathcmp(
2525 				 alist_name(&WARGLIST(win)[win->w_arg_idx]),
2526 				win->w_buffer->b_ffname, TRUE) & FPC_SAME))));
2527 }
2528 
2529 /*
2530  * Check if window "win" is editing the w_arg_idx file in its argument list.
2531  */
2532     void
2533 check_arg_idx(win_T *win)
2534 {
2535     if (WARGCOUNT(win) > 1 && !editing_arg_idx(win))
2536     {
2537 	/* We are not editing the current entry in the argument list.
2538 	 * Set "arg_had_last" if we are editing the last one. */
2539 	win->w_arg_idx_invalid = TRUE;
2540 	if (win->w_arg_idx != WARGCOUNT(win) - 1
2541 		&& arg_had_last == FALSE
2542 #ifdef FEAT_WINDOWS
2543 		&& ALIST(win) == &global_alist
2544 #endif
2545 		&& GARGCOUNT > 0
2546 		&& win->w_arg_idx < GARGCOUNT
2547 		&& (win->w_buffer->b_fnum == GARGLIST[GARGCOUNT - 1].ae_fnum
2548 		    || (win->w_buffer->b_ffname != NULL
2549 			&& (fullpathcmp(alist_name(&GARGLIST[GARGCOUNT - 1]),
2550 				win->w_buffer->b_ffname, TRUE) & FPC_SAME))))
2551 	    arg_had_last = TRUE;
2552     }
2553     else
2554     {
2555 	/* We are editing the current entry in the argument list.
2556 	 * Set "arg_had_last" if it's also the last one */
2557 	win->w_arg_idx_invalid = FALSE;
2558 	if (win->w_arg_idx == WARGCOUNT(win) - 1
2559 #ifdef FEAT_WINDOWS
2560 		&& win->w_alist == &global_alist
2561 #endif
2562 		)
2563 	    arg_had_last = TRUE;
2564     }
2565 }
2566 
2567 /*
2568  * ":args", ":argslocal" and ":argsglobal".
2569  */
2570     void
2571 ex_args(exarg_T *eap)
2572 {
2573     int		i;
2574 
2575     if (eap->cmdidx != CMD_args)
2576     {
2577 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
2578 	alist_unlink(ALIST(curwin));
2579 	if (eap->cmdidx == CMD_argglobal)
2580 	    ALIST(curwin) = &global_alist;
2581 	else /* eap->cmdidx == CMD_arglocal */
2582 	    alist_new();
2583 #else
2584 	ex_ni(eap);
2585 	return;
2586 #endif
2587     }
2588 
2589     if (!ends_excmd(*eap->arg))
2590     {
2591 	/*
2592 	 * ":args file ..": define new argument list, handle like ":next"
2593 	 * Also for ":argslocal file .." and ":argsglobal file ..".
2594 	 */
2595 	ex_next(eap);
2596     }
2597     else
2598 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
2599 	if (eap->cmdidx == CMD_args)
2600 #endif
2601     {
2602 	/*
2603 	 * ":args": list arguments.
2604 	 */
2605 	if (ARGCOUNT > 0)
2606 	{
2607 	    /* Overwrite the command, for a short list there is no scrolling
2608 	     * required and no wait_return(). */
2609 	    gotocmdline(TRUE);
2610 	    for (i = 0; i < ARGCOUNT; ++i)
2611 	    {
2612 		if (i == curwin->w_arg_idx)
2613 		    msg_putchar('[');
2614 		msg_outtrans(alist_name(&ARGLIST[i]));
2615 		if (i == curwin->w_arg_idx)
2616 		    msg_putchar(']');
2617 		msg_putchar(' ');
2618 	    }
2619 	}
2620     }
2621 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
2622     else if (eap->cmdidx == CMD_arglocal)
2623     {
2624 	garray_T	*gap = &curwin->w_alist->al_ga;
2625 
2626 	/*
2627 	 * ":argslocal": make a local copy of the global argument list.
2628 	 */
2629 	if (ga_grow(gap, GARGCOUNT) == OK)
2630 	    for (i = 0; i < GARGCOUNT; ++i)
2631 		if (GARGLIST[i].ae_fname != NULL)
2632 		{
2633 		    AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname =
2634 					    vim_strsave(GARGLIST[i].ae_fname);
2635 		    AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
2636 							  GARGLIST[i].ae_fnum;
2637 		    ++gap->ga_len;
2638 		}
2639     }
2640 #endif
2641 }
2642 
2643 /*
2644  * ":previous", ":sprevious", ":Next" and ":sNext".
2645  */
2646     void
2647 ex_previous(exarg_T *eap)
2648 {
2649     /* If past the last one already, go to the last one. */
2650     if (curwin->w_arg_idx - (int)eap->line2 >= ARGCOUNT)
2651 	do_argfile(eap, ARGCOUNT - 1);
2652     else
2653 	do_argfile(eap, curwin->w_arg_idx - (int)eap->line2);
2654 }
2655 
2656 /*
2657  * ":rewind", ":first", ":sfirst" and ":srewind".
2658  */
2659     void
2660 ex_rewind(exarg_T *eap)
2661 {
2662     do_argfile(eap, 0);
2663 }
2664 
2665 /*
2666  * ":last" and ":slast".
2667  */
2668     void
2669 ex_last(exarg_T *eap)
2670 {
2671     do_argfile(eap, ARGCOUNT - 1);
2672 }
2673 
2674 /*
2675  * ":argument" and ":sargument".
2676  */
2677     void
2678 ex_argument(exarg_T *eap)
2679 {
2680     int		i;
2681 
2682     if (eap->addr_count > 0)
2683 	i = eap->line2 - 1;
2684     else
2685 	i = curwin->w_arg_idx;
2686     do_argfile(eap, i);
2687 }
2688 
2689 /*
2690  * Edit file "argn" of the argument lists.
2691  */
2692     void
2693 do_argfile(exarg_T *eap, int argn)
2694 {
2695     int		other;
2696     char_u	*p;
2697     int		old_arg_idx = curwin->w_arg_idx;
2698 
2699     if (argn < 0 || argn >= ARGCOUNT)
2700     {
2701 	if (ARGCOUNT <= 1)
2702 	    EMSG(_("E163: There is only one file to edit"));
2703 	else if (argn < 0)
2704 	    EMSG(_("E164: Cannot go before first file"));
2705 	else
2706 	    EMSG(_("E165: Cannot go beyond last file"));
2707     }
2708     else
2709     {
2710 	setpcmark();
2711 #ifdef FEAT_GUI
2712 	need_mouse_correct = TRUE;
2713 #endif
2714 
2715 #ifdef FEAT_WINDOWS
2716 	/* split window or create new tab page first */
2717 	if (*eap->cmd == 's' || cmdmod.tab != 0)
2718 	{
2719 	    if (win_split(0, 0) == FAIL)
2720 		return;
2721 	    RESET_BINDING(curwin);
2722 	}
2723 	else
2724 #endif
2725 	{
2726 	    /*
2727 	     * if 'hidden' set, only check for changed file when re-editing
2728 	     * the same buffer
2729 	     */
2730 	    other = TRUE;
2731 	    if (P_HID(curbuf))
2732 	    {
2733 		p = fix_fname(alist_name(&ARGLIST[argn]));
2734 		other = otherfile(p);
2735 		vim_free(p);
2736 	    }
2737 	    if ((!P_HID(curbuf) || !other)
2738 		  && check_changed(curbuf, CCGD_AW
2739 					 | (other ? 0 : CCGD_MULTWIN)
2740 					 | (eap->forceit ? CCGD_FORCEIT : 0)
2741 					 | CCGD_EXCMD))
2742 		return;
2743 	}
2744 
2745 	curwin->w_arg_idx = argn;
2746 	if (argn == ARGCOUNT - 1
2747 #ifdef FEAT_WINDOWS
2748 		&& curwin->w_alist == &global_alist
2749 #endif
2750 	   )
2751 	    arg_had_last = TRUE;
2752 
2753 	/* Edit the file; always use the last known line number.
2754 	 * When it fails (e.g. Abort for already edited file) restore the
2755 	 * argument index. */
2756 	if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
2757 		      eap, ECMD_LAST,
2758 		      (P_HID(curwin->w_buffer) ? ECMD_HIDE : 0)
2759 			 + (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
2760 	    curwin->w_arg_idx = old_arg_idx;
2761 	/* like Vi: set the mark where the cursor is in the file. */
2762 	else if (eap->cmdidx != CMD_argdo)
2763 	    setmark('\'');
2764     }
2765 }
2766 
2767 /*
2768  * ":next", and commands that behave like it.
2769  */
2770     void
2771 ex_next(exarg_T *eap)
2772 {
2773     int		i;
2774 
2775     /*
2776      * check for changed buffer now, if this fails the argument list is not
2777      * redefined.
2778      */
2779     if (       P_HID(curbuf)
2780 	    || eap->cmdidx == CMD_snext
2781 	    || !check_changed(curbuf, CCGD_AW
2782 				    | (eap->forceit ? CCGD_FORCEIT : 0)
2783 				    | CCGD_EXCMD))
2784     {
2785 	if (*eap->arg != NUL)		    /* redefine file list */
2786 	{
2787 	    if (do_arglist(eap->arg, AL_SET, 0) == FAIL)
2788 		return;
2789 	    i = 0;
2790 	}
2791 	else
2792 	    i = curwin->w_arg_idx + (int)eap->line2;
2793 	do_argfile(eap, i);
2794     }
2795 }
2796 
2797 #if defined(FEAT_LISTCMDS) || defined(PROTO)
2798 /*
2799  * ":argedit"
2800  */
2801     void
2802 ex_argedit(exarg_T *eap)
2803 {
2804     int i = eap->addr_count ? (int)eap->line2 : curwin->w_arg_idx + 1;
2805 
2806     if (do_arglist(eap->arg, AL_ADD, i) == FAIL)
2807 	return;
2808 #ifdef FEAT_TITLE
2809     maketitle();
2810 #endif
2811 
2812     if (curwin->w_arg_idx == 0 && (curbuf->b_ml.ml_flags & ML_EMPTY)
2813 	    && curbuf->b_ffname == NULL)
2814 	i = 0;
2815     /* Edit the argument. */
2816     if (i < ARGCOUNT)
2817 	do_argfile(eap, i);
2818 }
2819 
2820 /*
2821  * ":argadd"
2822  */
2823     void
2824 ex_argadd(exarg_T *eap)
2825 {
2826     do_arglist(eap->arg, AL_ADD,
2827 	       eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
2828 #ifdef FEAT_TITLE
2829     maketitle();
2830 #endif
2831 }
2832 
2833 /*
2834  * ":argdelete"
2835  */
2836     void
2837 ex_argdelete(exarg_T *eap)
2838 {
2839     int		i;
2840     int		n;
2841 
2842     if (eap->addr_count > 0)
2843     {
2844 	/* ":1,4argdel": Delete all arguments in the range. */
2845 	if (eap->line2 > ARGCOUNT)
2846 	    eap->line2 = ARGCOUNT;
2847 	n = eap->line2 - eap->line1 + 1;
2848 	if (*eap->arg != NUL)
2849 	    /* Can't have both a range and an argument. */
2850 	    EMSG(_(e_invarg));
2851 	else if (n <= 0)
2852 	{
2853 	    /* Don't give an error for ":%argdel" if the list is empty. */
2854 	    if (eap->line1 != 1 || eap->line2 != 0)
2855 		EMSG(_(e_invrange));
2856 	}
2857 	else
2858 	{
2859 	    for (i = eap->line1; i <= eap->line2; ++i)
2860 		vim_free(ARGLIST[i - 1].ae_fname);
2861 	    mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2,
2862 			(size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T)));
2863 	    ALIST(curwin)->al_ga.ga_len -= n;
2864 	    if (curwin->w_arg_idx >= eap->line2)
2865 		curwin->w_arg_idx -= n;
2866 	    else if (curwin->w_arg_idx > eap->line1)
2867 		curwin->w_arg_idx = eap->line1;
2868 	    if (ARGCOUNT == 0)
2869 		curwin->w_arg_idx = 0;
2870 	    else if (curwin->w_arg_idx >= ARGCOUNT)
2871 		curwin->w_arg_idx = ARGCOUNT - 1;
2872 	}
2873     }
2874     else if (*eap->arg == NUL)
2875 	EMSG(_(e_argreq));
2876     else
2877 	do_arglist(eap->arg, AL_DEL, 0);
2878 #ifdef FEAT_TITLE
2879     maketitle();
2880 #endif
2881 }
2882 
2883 /*
2884  * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo"
2885  */
2886     void
2887 ex_listdo(exarg_T *eap)
2888 {
2889     int		i;
2890 #ifdef FEAT_WINDOWS
2891     win_T	*wp;
2892     tabpage_T	*tp;
2893 #endif
2894     buf_T	*buf = curbuf;
2895     int		next_fnum = 0;
2896 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2897     char_u	*save_ei = NULL;
2898 #endif
2899     char_u	*p_shm_save;
2900 #ifdef FEAT_QUICKFIX
2901     int		qf_size = 0;
2902     int		qf_idx;
2903 #endif
2904 
2905 #ifndef FEAT_WINDOWS
2906     if (eap->cmdidx == CMD_windo)
2907     {
2908 	ex_ni(eap);
2909 	return;
2910     }
2911 #endif
2912 
2913 #ifndef FEAT_QUICKFIX
2914     if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo ||
2915 	    eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
2916     {
2917 	ex_ni(eap);
2918 	return;
2919     }
2920 #endif
2921 
2922 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2923     if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo)
2924 	/* Don't do syntax HL autocommands.  Skipping the syntax file is a
2925 	 * great speed improvement. */
2926 	save_ei = au_event_disable(",Syntax");
2927 #endif
2928 #ifdef FEAT_CLIPBOARD
2929     start_global_changes();
2930 #endif
2931 
2932     if (eap->cmdidx == CMD_windo
2933 	    || eap->cmdidx == CMD_tabdo
2934 	    || P_HID(curbuf)
2935 	    || !check_changed(curbuf, CCGD_AW
2936 				    | (eap->forceit ? CCGD_FORCEIT : 0)
2937 				    | CCGD_EXCMD))
2938     {
2939 	i = 0;
2940 	/* start at the eap->line1 argument/window/buffer */
2941 #ifdef FEAT_WINDOWS
2942 	wp = firstwin;
2943 	tp = first_tabpage;
2944 #endif
2945 	switch (eap->cmdidx)
2946 	{
2947 #ifdef FEAT_WINDOWS
2948 	    case CMD_windo:
2949 		for ( ; wp != NULL && i + 1 < eap->line1; wp = wp->w_next)
2950 		    i++;
2951 		break;
2952 	    case CMD_tabdo:
2953 		for( ; tp != NULL && i + 1 < eap->line1; tp = tp->tp_next)
2954 		    i++;
2955 		break;
2956 #endif
2957 	    case CMD_argdo:
2958 		i = eap->line1 - 1;
2959 		break;
2960 	    default:
2961 		break;
2962 	}
2963 	/* set pcmark now */
2964 	if (eap->cmdidx == CMD_bufdo)
2965 	{
2966 	    /* Advance to the first listed buffer after "eap->line1". */
2967 	    for (buf = firstbuf; buf != NULL && (buf->b_fnum < eap->line1
2968 					  || !buf->b_p_bl); buf = buf->b_next)
2969 		if (buf->b_fnum > eap->line2)
2970 		{
2971 		    buf = NULL;
2972 		    break;
2973 		}
2974 	    if (buf != NULL)
2975 		goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum);
2976 	}
2977 #ifdef FEAT_QUICKFIX
2978 	else if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
2979 		|| eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
2980 	{
2981 	    qf_size = qf_get_size(eap);
2982 	    if (qf_size <= 0 || eap->line1 > qf_size)
2983 		buf = NULL;
2984 	    else
2985 	    {
2986 		ex_cc(eap);
2987 
2988 		buf = curbuf;
2989 		i = eap->line1 - 1;
2990 		if (eap->addr_count <= 0)
2991 		    /* default is all the quickfix/location list entries */
2992 		    eap->line2 = qf_size;
2993 	    }
2994 	}
2995 #endif
2996 	else
2997 	    setpcmark();
2998 	listcmd_busy = TRUE;	    /* avoids setting pcmark below */
2999 
3000 	while (!got_int && buf != NULL)
3001 	{
3002 	    if (eap->cmdidx == CMD_argdo)
3003 	    {
3004 		/* go to argument "i" */
3005 		if (i == ARGCOUNT)
3006 		    break;
3007 		/* Don't call do_argfile() when already there, it will try
3008 		 * reloading the file. */
3009 		if (curwin->w_arg_idx != i || !editing_arg_idx(curwin))
3010 		{
3011 		    /* Clear 'shm' to avoid that the file message overwrites
3012 		     * any output from the command. */
3013 		    p_shm_save = vim_strsave(p_shm);
3014 		    set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
3015 		    do_argfile(eap, i);
3016 		    set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
3017 		    vim_free(p_shm_save);
3018 		}
3019 		if (curwin->w_arg_idx != i)
3020 		    break;
3021 	    }
3022 #ifdef FEAT_WINDOWS
3023 	    else if (eap->cmdidx == CMD_windo)
3024 	    {
3025 		/* go to window "wp" */
3026 		if (!win_valid(wp))
3027 		    break;
3028 		win_goto(wp);
3029 		if (curwin != wp)
3030 		    break;  /* something must be wrong */
3031 		wp = curwin->w_next;
3032 	    }
3033 	    else if (eap->cmdidx == CMD_tabdo)
3034 	    {
3035 		/* go to window "tp" */
3036 		if (!valid_tabpage(tp))
3037 		    break;
3038 		goto_tabpage_tp(tp, TRUE, TRUE);
3039 		tp = tp->tp_next;
3040 	    }
3041 #endif
3042 	    else if (eap->cmdidx == CMD_bufdo)
3043 	    {
3044 		/* Remember the number of the next listed buffer, in case
3045 		 * ":bwipe" is used or autocommands do something strange. */
3046 		next_fnum = -1;
3047 		for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
3048 		    if (buf->b_p_bl)
3049 		    {
3050 			next_fnum = buf->b_fnum;
3051 			break;
3052 		    }
3053 	    }
3054 
3055 	    ++i;
3056 
3057 	    /* execute the command */
3058 	    do_cmdline(eap->arg, eap->getline, eap->cookie,
3059 						DOCMD_VERBOSE + DOCMD_NOWAIT);
3060 
3061 	    if (eap->cmdidx == CMD_bufdo)
3062 	    {
3063 		/* Done? */
3064 		if (next_fnum < 0 || next_fnum > eap->line2)
3065 		    break;
3066 		/* Check if the buffer still exists. */
3067 		FOR_ALL_BUFFERS(buf)
3068 		    if (buf->b_fnum == next_fnum)
3069 			break;
3070 		if (buf == NULL)
3071 		    break;
3072 
3073 		/* Go to the next buffer.  Clear 'shm' to avoid that the file
3074 		 * message overwrites any output from the command. */
3075 		p_shm_save = vim_strsave(p_shm);
3076 		set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
3077 		goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
3078 		set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
3079 		vim_free(p_shm_save);
3080 
3081 		/* If autocommands took us elsewhere, quit here. */
3082 		if (curbuf->b_fnum != next_fnum)
3083 		    break;
3084 	    }
3085 
3086 #ifdef FEAT_QUICKFIX
3087 	    if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
3088 		    || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
3089 	    {
3090 		if (i >= qf_size || i >= eap->line2)
3091 		    break;
3092 
3093 		qf_idx = qf_get_cur_idx(eap);
3094 
3095 		ex_cnext(eap);
3096 
3097 		/* If jumping to the next quickfix entry fails, quit here */
3098 		if (qf_get_cur_idx(eap) == qf_idx)
3099 		    break;
3100 	    }
3101 #endif
3102 
3103 	    if (eap->cmdidx == CMD_windo)
3104 	    {
3105 		validate_cursor();	/* cursor may have moved */
3106 #ifdef FEAT_SCROLLBIND
3107 		/* required when 'scrollbind' has been set */
3108 		if (curwin->w_p_scb)
3109 		    do_check_scrollbind(TRUE);
3110 #endif
3111 	    }
3112 
3113 #ifdef FEAT_WINDOWS
3114 	    if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo)
3115 		if (i+1 > eap->line2)
3116 		    break;
3117 #endif
3118 	    if (eap->cmdidx == CMD_argdo && i >= eap->line2)
3119 		break;
3120 	}
3121 	listcmd_busy = FALSE;
3122     }
3123 
3124 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
3125     if (save_ei != NULL)
3126     {
3127 	au_event_restore(save_ei);
3128 	apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
3129 					       curbuf->b_fname, TRUE, curbuf);
3130     }
3131 #endif
3132 #ifdef FEAT_CLIPBOARD
3133     end_global_changes();
3134 #endif
3135 }
3136 
3137 /*
3138  * Add files[count] to the arglist of the current window after arg "after".
3139  * The file names in files[count] must have been allocated and are taken over.
3140  * Files[] itself is not taken over.
3141  * Returns index of first added argument.  Returns -1 when failed (out of mem).
3142  */
3143     static int
3144 alist_add_list(
3145     int		count,
3146     char_u	**files,
3147     int		after)	    /* where to add: 0 = before first one */
3148 {
3149     int		i;
3150     int		old_argcount = ARGCOUNT;
3151 
3152     if (ga_grow(&ALIST(curwin)->al_ga, count) == OK)
3153     {
3154 	if (after < 0)
3155 	    after = 0;
3156 	if (after > ARGCOUNT)
3157 	    after = ARGCOUNT;
3158 	if (after < ARGCOUNT)
3159 	    mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
3160 				       (ARGCOUNT - after) * sizeof(aentry_T));
3161 	for (i = 0; i < count; ++i)
3162 	{
3163 	    ARGLIST[after + i].ae_fname = files[i];
3164 	    ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
3165 	}
3166 	ALIST(curwin)->al_ga.ga_len += count;
3167 	if (old_argcount > 0 && curwin->w_arg_idx >= after)
3168 	    curwin->w_arg_idx += count;
3169 	return after;
3170     }
3171 
3172     for (i = 0; i < count; ++i)
3173 	vim_free(files[i]);
3174     return -1;
3175 }
3176 
3177 #endif /* FEAT_LISTCMDS */
3178 
3179 #ifdef FEAT_EVAL
3180 /*
3181  * ":compiler[!] {name}"
3182  */
3183     void
3184 ex_compiler(exarg_T *eap)
3185 {
3186     char_u	*buf;
3187     char_u	*old_cur_comp = NULL;
3188     char_u	*p;
3189 
3190     if (*eap->arg == NUL)
3191     {
3192 	/* List all compiler scripts. */
3193 	do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')");
3194 					/* ) keep the indenter happy... */
3195     }
3196     else
3197     {
3198 	buf = alloc((unsigned)(STRLEN(eap->arg) + 14));
3199 	if (buf != NULL)
3200 	{
3201 	    if (eap->forceit)
3202 	    {
3203 		/* ":compiler! {name}" sets global options */
3204 		do_cmdline_cmd((char_u *)
3205 				   "command -nargs=* CompilerSet set <args>");
3206 	    }
3207 	    else
3208 	    {
3209 		/* ":compiler! {name}" sets local options.
3210 		 * To remain backwards compatible "current_compiler" is always
3211 		 * used.  A user's compiler plugin may set it, the distributed
3212 		 * plugin will then skip the settings.  Afterwards set
3213 		 * "b:current_compiler" and restore "current_compiler".
3214 		 * Explicitly prepend "g:" to make it work in a function. */
3215 		old_cur_comp = get_var_value((char_u *)"g:current_compiler");
3216 		if (old_cur_comp != NULL)
3217 		    old_cur_comp = vim_strsave(old_cur_comp);
3218 		do_cmdline_cmd((char_u *)
3219 			      "command -nargs=* CompilerSet setlocal <args>");
3220 	    }
3221 	    do_unlet((char_u *)"g:current_compiler", TRUE);
3222 	    do_unlet((char_u *)"b:current_compiler", TRUE);
3223 
3224 	    sprintf((char *)buf, "compiler/%s.vim", eap->arg);
3225 	    if (source_runtime(buf, DIP_ALL) == FAIL)
3226 		EMSG2(_("E666: compiler not supported: %s"), eap->arg);
3227 	    vim_free(buf);
3228 
3229 	    do_cmdline_cmd((char_u *)":delcommand CompilerSet");
3230 
3231 	    /* Set "b:current_compiler" from "current_compiler". */
3232 	    p = get_var_value((char_u *)"g:current_compiler");
3233 	    if (p != NULL)
3234 		set_internal_string_var((char_u *)"b:current_compiler", p);
3235 
3236 	    /* Restore "current_compiler" for ":compiler {name}". */
3237 	    if (!eap->forceit)
3238 	    {
3239 		if (old_cur_comp != NULL)
3240 		{
3241 		    set_internal_string_var((char_u *)"g:current_compiler",
3242 								old_cur_comp);
3243 		    vim_free(old_cur_comp);
3244 		}
3245 		else
3246 		    do_unlet((char_u *)"g:current_compiler", TRUE);
3247 	    }
3248 	}
3249     }
3250 }
3251 #endif
3252 
3253 /*
3254  * ":runtime [what] {name}"
3255  */
3256     void
3257 ex_runtime(exarg_T *eap)
3258 {
3259     char_u  *arg = eap->arg;
3260     char_u  *p = skiptowhite(arg);
3261     int	    len = (int)(p - arg);
3262     int	    flags = eap->forceit ? DIP_ALL : 0;
3263 
3264     if (STRNCMP(arg, "START", len) == 0)
3265     {
3266 	flags += DIP_START + DIP_NORTP;
3267 	arg = skipwhite(arg + len);
3268     }
3269     else if (STRNCMP(arg, "OPT", len) == 0)
3270     {
3271 	flags += DIP_OPT + DIP_NORTP;
3272 	arg = skipwhite(arg + len);
3273     }
3274     else if (STRNCMP(arg, "PACK", len) == 0)
3275     {
3276 	flags += DIP_START + DIP_OPT + DIP_NORTP;
3277 	arg = skipwhite(arg + len);
3278     }
3279     else if (STRNCMP(arg, "ALL", len) == 0)
3280     {
3281 	flags += DIP_START + DIP_OPT;
3282 	arg = skipwhite(arg + len);
3283     }
3284 
3285     source_runtime(arg, flags);
3286 }
3287 
3288     static void
3289 source_callback(char_u *fname, void *cookie UNUSED)
3290 {
3291     (void)do_source(fname, FALSE, DOSO_NONE);
3292 }
3293 
3294 /*
3295  * Find the file "name" in all directories in "path" and invoke
3296  * "callback(fname, cookie)".
3297  * "name" can contain wildcards.
3298  * When "flags" has DIP_ALL: source all files, otherwise only the first one.
3299  * When "flags" has DIP_DIR: find directories instead of files.
3300  * When "flags" has DIP_ERR: give an error message if there is no match.
3301  *
3302  * return FAIL when no file could be sourced, OK otherwise.
3303  */
3304     int
3305 do_in_path(
3306     char_u	*path,
3307     char_u	*name,
3308     int		flags,
3309     void	(*callback)(char_u *fname, void *ck),
3310     void	*cookie)
3311 {
3312     char_u	*rtp;
3313     char_u	*np;
3314     char_u	*buf;
3315     char_u	*rtp_copy;
3316     char_u	*tail;
3317     int		num_files;
3318     char_u	**files;
3319     int		i;
3320     int		did_one = FALSE;
3321 #ifdef AMIGA
3322     struct Process	*proc = (struct Process *)FindTask(0L);
3323     APTR		save_winptr = proc->pr_WindowPtr;
3324 
3325     /* Avoid a requester here for a volume that doesn't exist. */
3326     proc->pr_WindowPtr = (APTR)-1L;
3327 #endif
3328 
3329     /* Make a copy of 'runtimepath'.  Invoking the callback may change the
3330      * value. */
3331     rtp_copy = vim_strsave(path);
3332     buf = alloc(MAXPATHL);
3333     if (buf != NULL && rtp_copy != NULL)
3334     {
3335 	if (p_verbose > 1 && name != NULL)
3336 	{
3337 	    verbose_enter();
3338 	    smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
3339 						 (char *)name, (char *)path);
3340 	    verbose_leave();
3341 	}
3342 
3343 	/* Loop over all entries in 'runtimepath'. */
3344 	rtp = rtp_copy;
3345 	while (*rtp != NUL && ((flags & DIP_ALL) || !did_one))
3346 	{
3347 	    size_t buflen;
3348 
3349 	    /* Copy the path from 'runtimepath' to buf[]. */
3350 	    copy_option_part(&rtp, buf, MAXPATHL, ",");
3351 	    buflen = STRLEN(buf);
3352 
3353 	    /* Skip after or non-after directories. */
3354 	    if (flags & (DIP_NOAFTER | DIP_AFTER))
3355 	    {
3356 		int is_after = buflen >= 5
3357 				     && STRCMP(buf + buflen - 5, "after") == 0;
3358 
3359 		if ((is_after && (flags & DIP_NOAFTER))
3360 			|| (!is_after && (flags & DIP_AFTER)))
3361 		    continue;
3362 	    }
3363 
3364 	    if (name == NULL)
3365 	    {
3366 		(*callback)(buf, (void *) &cookie);
3367 		if (!did_one)
3368 		    did_one = (cookie == NULL);
3369 	    }
3370 	    else if (buflen + STRLEN(name) + 2 < MAXPATHL)
3371 	    {
3372 		add_pathsep(buf);
3373 		tail = buf + STRLEN(buf);
3374 
3375 		/* Loop over all patterns in "name" */
3376 		np = name;
3377 		while (*np != NUL && ((flags & DIP_ALL) || !did_one))
3378 		{
3379 		    /* Append the pattern from "name" to buf[]. */
3380 		    copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)),
3381 								       "\t ");
3382 
3383 		    if (p_verbose > 2)
3384 		    {
3385 			verbose_enter();
3386 			smsg((char_u *)_("Searching for \"%s\""), buf);
3387 			verbose_leave();
3388 		    }
3389 
3390 		    /* Expand wildcards, invoke the callback for each match. */
3391 		    if (gen_expand_wildcards(1, &buf, &num_files, &files,
3392 				  (flags & DIP_DIR) ? EW_DIR : EW_FILE) == OK)
3393 		    {
3394 			for (i = 0; i < num_files; ++i)
3395 			{
3396 			    (*callback)(files[i], cookie);
3397 			    did_one = TRUE;
3398 			    if (!(flags & DIP_ALL))
3399 				break;
3400 			}
3401 			FreeWild(num_files, files);
3402 		    }
3403 		}
3404 	    }
3405 	}
3406     }
3407     vim_free(buf);
3408     vim_free(rtp_copy);
3409     if (!did_one && name != NULL)
3410     {
3411 	char *basepath = path == p_rtp ? "runtimepath" : "packpath";
3412 
3413 	if (flags & DIP_ERR)
3414 	    EMSG3(_(e_dirnotf), basepath, name);
3415 	else if (p_verbose > 0)
3416 	{
3417 	    verbose_enter();
3418 	    smsg((char_u *)_("not found in '%s': \"%s\""), basepath, name);
3419 	    verbose_leave();
3420 	}
3421     }
3422 
3423 #ifdef AMIGA
3424     proc->pr_WindowPtr = save_winptr;
3425 #endif
3426 
3427     return did_one ? OK : FAIL;
3428 }
3429 
3430 /*
3431  * Find "name" in "path".  When found, invoke the callback function for
3432  * it: callback(fname, "cookie")
3433  * When "flags" has DIP_ALL repeat for all matches, otherwise only the first
3434  * one is used.
3435  * Returns OK when at least one match found, FAIL otherwise.
3436  *
3437  * If "name" is NULL calls callback for each entry in "path". Cookie is
3438  * passed by reference in this case, setting it to NULL indicates that callback
3439  * has done its job.
3440  */
3441     static int
3442 do_in_path_and_pp(
3443     char_u	*path,
3444     char_u	*name,
3445     int		flags,
3446     void	(*callback)(char_u *fname, void *ck),
3447     void	*cookie)
3448 {
3449     int		done = FAIL;
3450     char_u	*s;
3451     int		len;
3452     char	*start_dir = "pack/*/start/*/%s";
3453     char	*opt_dir = "pack/*/opt/*/%s";
3454 
3455     if ((flags & DIP_NORTP) == 0)
3456 	done = do_in_path(path, name, flags, callback, cookie);
3457 
3458     if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START))
3459     {
3460 	len = (int)(STRLEN(start_dir) + STRLEN(name));
3461 	s = alloc(len);
3462 	if (s == NULL)
3463 	    return FAIL;
3464 	vim_snprintf((char *)s, len, start_dir, name);
3465 	done = do_in_path(p_pp, s, flags, callback, cookie);
3466 	vim_free(s);
3467     }
3468 
3469     if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_OPT))
3470     {
3471 	len = (int)(STRLEN(opt_dir) + STRLEN(name));
3472 	s = alloc(len);
3473 	if (s == NULL)
3474 	    return FAIL;
3475 	vim_snprintf((char *)s, len, opt_dir, name);
3476 	done = do_in_path(p_pp, s, flags, callback, cookie);
3477 	vim_free(s);
3478     }
3479 
3480     return done;
3481 }
3482 
3483 /*
3484  * Just like do_in_path_and_pp(), using 'runtimepath' for "path".
3485  */
3486     int
3487 do_in_runtimepath(
3488     char_u	*name,
3489     int		flags,
3490     void	(*callback)(char_u *fname, void *ck),
3491     void	*cookie)
3492 {
3493     return do_in_path_and_pp(p_rtp, name, flags, callback, cookie);
3494 }
3495 
3496 /*
3497  * Source the file "name" from all directories in 'runtimepath'.
3498  * "name" can contain wildcards.
3499  * When "flags" has DIP_ALL: source all files, otherwise only the first one.
3500  *
3501  * return FAIL when no file could be sourced, OK otherwise.
3502  */
3503     int
3504 source_runtime(char_u *name, int flags)
3505 {
3506     return source_in_path(p_rtp, name, flags);
3507 }
3508 
3509 /*
3510  * Just like source_runtime(), but use "path" instead of 'runtimepath'.
3511  */
3512     int
3513 source_in_path(char_u *path, char_u *name, int flags)
3514 {
3515     return do_in_path_and_pp(path, name, flags, source_callback, NULL);
3516 }
3517 
3518 
3519 /*
3520  * Expand wildcards in "pat" and invoke do_source() for each match.
3521  */
3522     static void
3523 source_all_matches(char_u *pat)
3524 {
3525     int	    num_files;
3526     char_u  **files;
3527     int	    i;
3528 
3529     if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK)
3530     {
3531 	for (i = 0; i < num_files; ++i)
3532 	    (void)do_source(files[i], FALSE, DOSO_NONE);
3533 	FreeWild(num_files, files);
3534     }
3535 }
3536 
3537 /* used for "cookie" of add_pack_plugin() */
3538 static int APP_ADD_DIR;
3539 static int APP_LOAD;
3540 static int APP_BOTH;
3541 
3542     static void
3543 add_pack_plugin(char_u *fname, void *cookie)
3544 {
3545     char_u  *p4, *p3, *p2, *p1, *p;
3546     char_u  *insp;
3547     int	    c;
3548     char_u  *new_rtp;
3549     int	    keep;
3550     size_t  oldlen;
3551     size_t  addlen;
3552     char_u  *afterdir;
3553     size_t  afterlen = 0;
3554     char_u  *ffname = fix_fname(fname);
3555     size_t  fname_len;
3556     char_u  *buf = NULL;
3557     char_u  *rtp_ffname;
3558     int	    match;
3559 
3560     if (ffname == NULL)
3561 	return;
3562     if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)ffname) == NULL)
3563     {
3564 	/* directory is not yet in 'runtimepath', add it */
3565 	p4 = p3 = p2 = p1 = get_past_head(ffname);
3566 	for (p = p1; *p; MB_PTR_ADV(p))
3567 	    if (vim_ispathsep_nocolon(*p))
3568 	    {
3569 		p4 = p3; p3 = p2; p2 = p1; p1 = p;
3570 	    }
3571 
3572 	/* now we have:
3573 	 * rtp/pack/name/start/name
3574 	 *    p4   p3   p2    p1
3575 	 *
3576 	 * find the part up to "pack" in 'runtimepath' */
3577 	c = *p4;
3578 	*p4 = NUL;
3579 
3580 	/* Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. */
3581 	fname_len = STRLEN(ffname);
3582 	insp = p_rtp;
3583 	buf = alloc(MAXPATHL);
3584 	if (buf == NULL)
3585 	    goto theend;
3586 	while (*insp != NUL)
3587 	{
3588 	    copy_option_part(&insp, buf, MAXPATHL, ",");
3589 	    add_pathsep(buf);
3590 	    rtp_ffname = fix_fname(buf);
3591 	    if (rtp_ffname == NULL)
3592 		goto theend;
3593 	    match = vim_fnamencmp(rtp_ffname, ffname, fname_len) == 0;
3594 	    vim_free(rtp_ffname);
3595 	    if (match)
3596 		break;
3597 	}
3598 
3599 	if (*insp == NUL)
3600 	    /* not found, append at the end */
3601 	    insp = p_rtp + STRLEN(p_rtp);
3602 	else
3603 	    /* append after the matching directory. */
3604 	    --insp;
3605 	*p4 = c;
3606 
3607 	/* check if rtp/pack/name/start/name/after exists */
3608 	afterdir = concat_fnames(ffname, (char_u *)"after", TRUE);
3609 	if (afterdir != NULL && mch_isdir(afterdir))
3610 	    afterlen = STRLEN(afterdir) + 1; /* add one for comma */
3611 
3612 	oldlen = STRLEN(p_rtp);
3613 	addlen = STRLEN(ffname) + 1; /* add one for comma */
3614 	new_rtp = alloc((int)(oldlen + addlen + afterlen + 1));
3615 							  /* add one for NUL */
3616 	if (new_rtp == NULL)
3617 	    goto theend;
3618 	keep = (int)(insp - p_rtp);
3619 	mch_memmove(new_rtp, p_rtp, keep);
3620 	new_rtp[keep] = ',';
3621 	mch_memmove(new_rtp + keep + 1, ffname, addlen);
3622 	if (p_rtp[keep] != NUL)
3623 	    mch_memmove(new_rtp + keep + addlen, p_rtp + keep,
3624 							   oldlen - keep + 1);
3625 	if (afterlen > 0)
3626 	{
3627 	    STRCAT(new_rtp, ",");
3628 	    STRCAT(new_rtp, afterdir);
3629 	}
3630 	set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
3631 	vim_free(new_rtp);
3632 	vim_free(afterdir);
3633     }
3634 
3635     if (cookie != &APP_ADD_DIR)
3636     {
3637 	static char *plugpat = "%s/plugin/**/*.vim";
3638 	static char *ftpat = "%s/ftdetect/*.vim";
3639 	int	    len;
3640 	char_u	    *pat;
3641 
3642 	len = (int)STRLEN(ffname) + (int)STRLEN(ftpat);
3643 	pat = alloc(len);
3644 	if (pat == NULL)
3645 	    goto theend;
3646 	vim_snprintf((char *)pat, len, plugpat, ffname);
3647 	source_all_matches(pat);
3648 
3649 #ifdef FEAT_AUTOCMD
3650 	{
3651 	    char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes");
3652 
3653 	    /* If runtime/filetype.vim wasn't loaded yet, the scripts will be
3654 	     * found when it loads. */
3655 	    if (cmd != NULL && eval_to_number(cmd) > 0)
3656 	    {
3657 		do_cmdline_cmd((char_u *)"augroup filetypedetect");
3658 		vim_snprintf((char *)pat, len, ftpat, ffname);
3659 		source_all_matches(pat);
3660 		do_cmdline_cmd((char_u *)"augroup END");
3661 	    }
3662 	    vim_free(cmd);
3663 	}
3664 #endif
3665 	vim_free(pat);
3666     }
3667 
3668 theend:
3669     vim_free(buf);
3670     vim_free(ffname);
3671 }
3672 
3673 /*
3674  * Add all packages in the "start" directory to 'runtimepath'.
3675  */
3676     void
3677 add_pack_start_dirs(void)
3678 {
3679     do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR,
3680 					       add_pack_plugin, &APP_ADD_DIR);
3681 }
3682 
3683 /*
3684  * Load plugins from all packages in the "start" directory.
3685  */
3686     void
3687 load_start_packages(void)
3688 {
3689     did_source_packages = TRUE;
3690     do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR,
3691 						  add_pack_plugin, &APP_LOAD);
3692 }
3693 
3694 /*
3695  * ":packloadall"
3696  * Find plugins in the package directories and source them.
3697  */
3698     void
3699 ex_packloadall(exarg_T *eap)
3700 {
3701     if (!did_source_packages || eap->forceit)
3702     {
3703 	/* First do a round to add all directories to 'runtimepath', then load
3704 	 * the plugins. This allows for plugins to use an autoload directory
3705 	 * of another plugin. */
3706 	add_pack_start_dirs();
3707 	load_start_packages();
3708     }
3709 }
3710 
3711 /*
3712  * ":packadd[!] {name}"
3713  */
3714     void
3715 ex_packadd(exarg_T *eap)
3716 {
3717     static char *plugpat = "pack/*/opt/%s";
3718     int		len;
3719     char	*pat;
3720 
3721     len = (int)STRLEN(plugpat) + (int)STRLEN(eap->arg);
3722     pat = (char *)alloc(len);
3723     if (pat == NULL)
3724 	return;
3725     vim_snprintf(pat, len, plugpat, eap->arg);
3726     do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR + DIP_ERR,
3727 		    add_pack_plugin, eap->forceit ? &APP_ADD_DIR : &APP_BOTH);
3728     vim_free(pat);
3729 }
3730 
3731 #if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
3732 /*
3733  * ":options"
3734  */
3735     void
3736 ex_options(
3737     exarg_T	*eap UNUSED)
3738 {
3739     cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
3740 }
3741 #endif
3742 
3743 #if defined(FEAT_PYTHON3) || defined(FEAT_PYTHON) || defined(PROTO)
3744 
3745 # if (defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)) || defined(PROTO)
3746 /*
3747  * Detect Python 3 or 2, and initialize 'pyxversion'.
3748  */
3749     void
3750 init_pyxversion(void)
3751 {
3752     if (p_pyx == 0)
3753     {
3754 	if (python3_enabled(FALSE))
3755 	    p_pyx = 3;
3756 	else if (python_enabled(FALSE))
3757 	    p_pyx = 2;
3758     }
3759 }
3760 # endif
3761 
3762 /*
3763  * Does a file contain one of the following strings at the beginning of any
3764  * line?
3765  * "#!(any string)python2"  => returns 2
3766  * "#!(any string)python3"  => returns 3
3767  * "# requires python 2.x"  => returns 2
3768  * "# requires python 3.x"  => returns 3
3769  * otherwise return 0.
3770  */
3771     static int
3772 requires_py_version(char_u *filename)
3773 {
3774     FILE    *file;
3775     int	    requires_py_version = 0;
3776     int	    i, lines;
3777 
3778     lines = (int)p_mls;
3779     if (lines < 0)
3780 	lines = 5;
3781 
3782     file = mch_fopen((char *)filename, "r");
3783     if (file != NULL)
3784     {
3785 	for (i = 0; i < lines; i++)
3786 	{
3787 	    if (vim_fgets(IObuff, IOSIZE, file))
3788 		break;
3789 	    if (i == 0 && IObuff[0] == '#' && IObuff[1] == '!')
3790 	    {
3791 		/* Check shebang. */
3792 		if (strstr((char *)IObuff + 2, "python2") != NULL)
3793 		{
3794 		    requires_py_version = 2;
3795 		    break;
3796 		}
3797 		if (strstr((char *)IObuff + 2, "python3") != NULL)
3798 		{
3799 		    requires_py_version = 3;
3800 		    break;
3801 		}
3802 	    }
3803 	    IObuff[21] = '\0';
3804 	    if (STRCMP("# requires python 2.x", IObuff) == 0)
3805 	    {
3806 		requires_py_version = 2;
3807 		break;
3808 	    }
3809 	    if (STRCMP("# requires python 3.x", IObuff) == 0)
3810 	    {
3811 		requires_py_version = 3;
3812 		break;
3813 	    }
3814 	}
3815 	fclose(file);
3816     }
3817     return requires_py_version;
3818 }
3819 
3820 
3821 /*
3822  * Source a python file using the requested python version.
3823  */
3824     static void
3825 source_pyx_file(exarg_T *eap, char_u *fname)
3826 {
3827     exarg_T ex;
3828     int	    v = requires_py_version(fname);
3829 
3830 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
3831     init_pyxversion();
3832 # endif
3833     if (v == 0)
3834     {
3835 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
3836 	/* user didn't choose a preference, 'pyx' is used */
3837 	v = p_pyx;
3838 # elif defined(FEAT_PYTHON)
3839 	v = 2;
3840 # elif defined(FEAT_PYTHON3)
3841 	v = 3;
3842 # endif
3843     }
3844 
3845     /*
3846      * now source, if required python version is not supported show
3847      * unobtrusive message.
3848      */
3849     if (eap == NULL)
3850 	vim_memset(&ex, 0, sizeof(ex));
3851     else
3852 	ex = *eap;
3853     ex.arg = fname;
3854     ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3");
3855 
3856     if (v == 2)
3857     {
3858 # ifdef FEAT_PYTHON
3859 	ex_pyfile(&ex);
3860 # else
3861 	vim_snprintf((char *)IObuff, IOSIZE,
3862 		_("W20: Required python version 2.x not supported, ignoring file: %s"),
3863 		fname);
3864 	MSG(IObuff);
3865 # endif
3866 	return;
3867     }
3868     else
3869     {
3870 # ifdef FEAT_PYTHON3
3871 	ex_py3file(&ex);
3872 # else
3873 	vim_snprintf((char *)IObuff, IOSIZE,
3874 		_("W21: Required python version 3.x not supported, ignoring file: %s"),
3875 		fname);
3876 	MSG(IObuff);
3877 # endif
3878 	return;
3879     }
3880 }
3881 
3882 /*
3883  * ":pyxfile {fname}"
3884  */
3885     void
3886 ex_pyxfile(exarg_T *eap)
3887 {
3888     source_pyx_file(eap, eap->arg);
3889 }
3890 
3891 /*
3892  * ":pyx"
3893  */
3894     void
3895 ex_pyx(exarg_T *eap)
3896 {
3897 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
3898     init_pyxversion();
3899     if (p_pyx == 2)
3900 	ex_python(eap);
3901     else
3902 	ex_py3(eap);
3903 # elif defined(FEAT_PYTHON)
3904     ex_python(eap);
3905 # elif defined(FEAT_PYTHON3)
3906     ex_py3(eap);
3907 # endif
3908 }
3909 
3910 /*
3911  * ":pyxdo"
3912  */
3913     void
3914 ex_pyxdo(exarg_T *eap)
3915 {
3916 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
3917     init_pyxversion();
3918     if (p_pyx == 2)
3919 	ex_pydo(eap);
3920     else
3921 	ex_py3do(eap);
3922 # elif defined(FEAT_PYTHON)
3923     ex_pydo(eap);
3924 # elif defined(FEAT_PYTHON3)
3925     ex_py3do(eap);
3926 # endif
3927 }
3928 
3929 #endif
3930 
3931 /*
3932  * ":source {fname}"
3933  */
3934     void
3935 ex_source(exarg_T *eap)
3936 {
3937 #ifdef FEAT_BROWSE
3938     if (cmdmod.browse)
3939     {
3940 	char_u *fname = NULL;
3941 
3942 	fname = do_browse(0, (char_u *)_("Source Vim script"), eap->arg,
3943 				      NULL, NULL, BROWSE_FILTER_MACROS, NULL);
3944 	if (fname != NULL)
3945 	{
3946 	    cmd_source(fname, eap);
3947 	    vim_free(fname);
3948 	}
3949     }
3950     else
3951 #endif
3952 	cmd_source(eap->arg, eap);
3953 }
3954 
3955     static void
3956 cmd_source(char_u *fname, exarg_T *eap)
3957 {
3958     if (*fname == NUL)
3959 	EMSG(_(e_argreq));
3960 
3961     else if (eap != NULL && eap->forceit)
3962 	/* ":source!": read Normal mode commands
3963 	 * Need to execute the commands directly.  This is required at least
3964 	 * for:
3965 	 * - ":g" command busy
3966 	 * - after ":argdo", ":windo" or ":bufdo"
3967 	 * - another command follows
3968 	 * - inside a loop
3969 	 */
3970 	openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL
3971 #ifdef FEAT_EVAL
3972 						 || eap->cstack->cs_idx >= 0
3973 #endif
3974 						 );
3975 
3976     /* ":source" read ex commands */
3977     else if (do_source(fname, FALSE, DOSO_NONE) == FAIL)
3978 	EMSG2(_(e_notopen), fname);
3979 }
3980 
3981 /*
3982  * ":source" and associated commands.
3983  */
3984 /*
3985  * Structure used to store info for each sourced file.
3986  * It is shared between do_source() and getsourceline().
3987  * This is required, because it needs to be handed to do_cmdline() and
3988  * sourcing can be done recursively.
3989  */
3990 struct source_cookie
3991 {
3992     FILE	*fp;		/* opened file for sourcing */
3993     char_u      *nextline;      /* if not NULL: line that was read ahead */
3994     int		finished;	/* ":finish" used */
3995 #if defined(USE_CRNL) || defined(USE_CR)
3996     int		fileformat;	/* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
3997     int		error;		/* TRUE if LF found after CR-LF */
3998 #endif
3999 #ifdef FEAT_EVAL
4000     linenr_T	breakpoint;	/* next line with breakpoint or zero */
4001     char_u	*fname;		/* name of sourced file */
4002     int		dbg_tick;	/* debug_tick when breakpoint was set */
4003     int		level;		/* top nesting level of sourced file */
4004 #endif
4005 #ifdef FEAT_MBYTE
4006     vimconv_T	conv;		/* type of conversion */
4007 #endif
4008 };
4009 
4010 #ifdef FEAT_EVAL
4011 /*
4012  * Return the address holding the next breakpoint line for a source cookie.
4013  */
4014     linenr_T *
4015 source_breakpoint(void *cookie)
4016 {
4017     return &((struct source_cookie *)cookie)->breakpoint;
4018 }
4019 
4020 /*
4021  * Return the address holding the debug tick for a source cookie.
4022  */
4023     int *
4024 source_dbg_tick(void *cookie)
4025 {
4026     return &((struct source_cookie *)cookie)->dbg_tick;
4027 }
4028 
4029 /*
4030  * Return the nesting level for a source cookie.
4031  */
4032     int
4033 source_level(void *cookie)
4034 {
4035     return ((struct source_cookie *)cookie)->level;
4036 }
4037 #endif
4038 
4039 static char_u *get_one_sourceline(struct source_cookie *sp);
4040 
4041 #if (defined(WIN32) && defined(FEAT_CSCOPE)) || defined(HAVE_FD_CLOEXEC)
4042 # define USE_FOPEN_NOINH
4043 static FILE *fopen_noinh_readbin(char *filename);
4044 
4045 /*
4046  * Special function to open a file without handle inheritance.
4047  * When possible the handle is closed on exec().
4048  */
4049     static FILE *
4050 fopen_noinh_readbin(char *filename)
4051 {
4052 # ifdef WIN32
4053     int	fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0);
4054 # else
4055     int	fd_tmp = mch_open(filename, O_RDONLY, 0);
4056 # endif
4057 
4058     if (fd_tmp == -1)
4059 	return NULL;
4060 
4061 # ifdef HAVE_FD_CLOEXEC
4062     {
4063 	int fdflags = fcntl(fd_tmp, F_GETFD);
4064 	if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
4065 	    (void)fcntl(fd_tmp, F_SETFD, fdflags | FD_CLOEXEC);
4066     }
4067 # endif
4068 
4069     return fdopen(fd_tmp, READBIN);
4070 }
4071 #endif
4072 
4073 
4074 /*
4075  * do_source: Read the file "fname" and execute its lines as EX commands.
4076  *
4077  * This function may be called recursively!
4078  *
4079  * return FAIL if file could not be opened, OK otherwise
4080  */
4081     int
4082 do_source(
4083     char_u	*fname,
4084     int		check_other,	    /* check for .vimrc and _vimrc */
4085     int		is_vimrc)	    /* DOSO_ value */
4086 {
4087     struct source_cookie    cookie;
4088     char_u		    *save_sourcing_name;
4089     linenr_T		    save_sourcing_lnum;
4090     char_u		    *p;
4091     char_u		    *fname_exp;
4092     char_u		    *firstline = NULL;
4093     int			    retval = FAIL;
4094 #ifdef FEAT_EVAL
4095     scid_T		    save_current_SID;
4096     static scid_T	    last_current_SID = 0;
4097     void		    *save_funccalp;
4098     int			    save_debug_break_level = debug_break_level;
4099     scriptitem_T	    *si = NULL;
4100 # ifdef UNIX
4101     stat_T		    st;
4102     int			    stat_ok;
4103 # endif
4104 #endif
4105 #ifdef STARTUPTIME
4106     struct timeval	    tv_rel;
4107     struct timeval	    tv_start;
4108 #endif
4109 #ifdef FEAT_PROFILE
4110     proftime_T		    wait_start;
4111 #endif
4112 
4113     p = expand_env_save(fname);
4114     if (p == NULL)
4115 	return retval;
4116     fname_exp = fix_fname(p);
4117     vim_free(p);
4118     if (fname_exp == NULL)
4119 	return retval;
4120     if (mch_isdir(fname_exp))
4121     {
4122 	smsg((char_u *)_("Cannot source a directory: \"%s\""), fname);
4123 	goto theend;
4124     }
4125 
4126 #ifdef FEAT_AUTOCMD
4127     /* Apply SourceCmd autocommands, they should get the file and source it. */
4128     if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
4129 	    && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
4130 							       FALSE, curbuf))
4131     {
4132 # ifdef FEAT_EVAL
4133 	retval = aborting() ? FAIL : OK;
4134 # else
4135 	retval = OK;
4136 # endif
4137 	goto theend;
4138     }
4139 
4140     /* Apply SourcePre autocommands, they may get the file. */
4141     apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
4142 #endif
4143 
4144 #ifdef USE_FOPEN_NOINH
4145     cookie.fp = fopen_noinh_readbin((char *)fname_exp);
4146 #else
4147     cookie.fp = mch_fopen((char *)fname_exp, READBIN);
4148 #endif
4149     if (cookie.fp == NULL && check_other)
4150     {
4151 	/*
4152 	 * Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
4153 	 * and ".exrc" by "_exrc" or vice versa.
4154 	 */
4155 	p = gettail(fname_exp);
4156 	if ((*p == '.' || *p == '_')
4157 		&& (STRICMP(p + 1, "vimrc") == 0
4158 		    || STRICMP(p + 1, "gvimrc") == 0
4159 		    || STRICMP(p + 1, "exrc") == 0))
4160 	{
4161 	    if (*p == '_')
4162 		*p = '.';
4163 	    else
4164 		*p = '_';
4165 #ifdef USE_FOPEN_NOINH
4166 	    cookie.fp = fopen_noinh_readbin((char *)fname_exp);
4167 #else
4168 	    cookie.fp = mch_fopen((char *)fname_exp, READBIN);
4169 #endif
4170 	}
4171     }
4172 
4173     if (cookie.fp == NULL)
4174     {
4175 	if (p_verbose > 0)
4176 	{
4177 	    verbose_enter();
4178 	    if (sourcing_name == NULL)
4179 		smsg((char_u *)_("could not source \"%s\""), fname);
4180 	    else
4181 		smsg((char_u *)_("line %ld: could not source \"%s\""),
4182 							sourcing_lnum, fname);
4183 	    verbose_leave();
4184 	}
4185 	goto theend;
4186     }
4187 
4188     /*
4189      * The file exists.
4190      * - In verbose mode, give a message.
4191      * - For a vimrc file, may want to set 'compatible', call vimrc_found().
4192      */
4193     if (p_verbose > 1)
4194     {
4195 	verbose_enter();
4196 	if (sourcing_name == NULL)
4197 	    smsg((char_u *)_("sourcing \"%s\""), fname);
4198 	else
4199 	    smsg((char_u *)_("line %ld: sourcing \"%s\""),
4200 							sourcing_lnum, fname);
4201 	verbose_leave();
4202     }
4203     if (is_vimrc == DOSO_VIMRC)
4204 	vimrc_found(fname_exp, (char_u *)"MYVIMRC");
4205     else if (is_vimrc == DOSO_GVIMRC)
4206 	vimrc_found(fname_exp, (char_u *)"MYGVIMRC");
4207 
4208 #ifdef USE_CRNL
4209     /* If no automatic file format: Set default to CR-NL. */
4210     if (*p_ffs == NUL)
4211 	cookie.fileformat = EOL_DOS;
4212     else
4213 	cookie.fileformat = EOL_UNKNOWN;
4214     cookie.error = FALSE;
4215 #endif
4216 
4217 #ifdef USE_CR
4218     /* If no automatic file format: Set default to CR. */
4219     if (*p_ffs == NUL)
4220 	cookie.fileformat = EOL_MAC;
4221     else
4222 	cookie.fileformat = EOL_UNKNOWN;
4223     cookie.error = FALSE;
4224 #endif
4225 
4226     cookie.nextline = NULL;
4227     cookie.finished = FALSE;
4228 
4229 #ifdef FEAT_EVAL
4230     /*
4231      * Check if this script has a breakpoint.
4232      */
4233     cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
4234     cookie.fname = fname_exp;
4235     cookie.dbg_tick = debug_tick;
4236 
4237     cookie.level = ex_nesting_level;
4238 #endif
4239 
4240     /*
4241      * Keep the sourcing name/lnum, for recursive calls.
4242      */
4243     save_sourcing_name = sourcing_name;
4244     sourcing_name = fname_exp;
4245     save_sourcing_lnum = sourcing_lnum;
4246     sourcing_lnum = 0;
4247 
4248 #ifdef FEAT_MBYTE
4249     cookie.conv.vc_type = CONV_NONE;		/* no conversion */
4250 
4251     /* Read the first line so we can check for a UTF-8 BOM. */
4252     firstline = getsourceline(0, (void *)&cookie, 0);
4253     if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
4254 			      && firstline[1] == 0xbb && firstline[2] == 0xbf)
4255     {
4256 	/* Found BOM; setup conversion, skip over BOM and recode the line. */
4257 	convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
4258 	p = string_convert(&cookie.conv, firstline + 3, NULL);
4259 	if (p == NULL)
4260 	    p = vim_strsave(firstline + 3);
4261 	if (p != NULL)
4262 	{
4263 	    vim_free(firstline);
4264 	    firstline = p;
4265 	}
4266     }
4267 #endif
4268 
4269 #ifdef STARTUPTIME
4270     if (time_fd != NULL)
4271 	time_push(&tv_rel, &tv_start);
4272 #endif
4273 
4274 #ifdef FEAT_EVAL
4275 # ifdef FEAT_PROFILE
4276     if (do_profiling == PROF_YES)
4277 	prof_child_enter(&wait_start);		/* entering a child now */
4278 # endif
4279 
4280     /* Don't use local function variables, if called from a function.
4281      * Also starts profiling timer for nested script. */
4282     save_funccalp = save_funccal();
4283 
4284     /*
4285      * Check if this script was sourced before to finds its SID.
4286      * If it's new, generate a new SID.
4287      */
4288     save_current_SID = current_SID;
4289 # ifdef UNIX
4290     stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
4291 # endif
4292     for (current_SID = script_items.ga_len; current_SID > 0; --current_SID)
4293     {
4294 	si = &SCRIPT_ITEM(current_SID);
4295 	if (si->sn_name != NULL
4296 		&& (
4297 # ifdef UNIX
4298 		    /* Compare dev/ino when possible, it catches symbolic
4299 		     * links.  Also compare file names, the inode may change
4300 		     * when the file was edited. */
4301 		    ((stat_ok && si->sn_dev_valid)
4302 			&& (si->sn_dev == st.st_dev
4303 			    && si->sn_ino == st.st_ino)) ||
4304 # endif
4305 		fnamecmp(si->sn_name, fname_exp) == 0))
4306 	    break;
4307     }
4308     if (current_SID == 0)
4309     {
4310 	current_SID = ++last_current_SID;
4311 	if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len))
4312 								      == FAIL)
4313 	    goto almosttheend;
4314 	while (script_items.ga_len < current_SID)
4315 	{
4316 	    ++script_items.ga_len;
4317 	    SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
4318 # ifdef FEAT_PROFILE
4319 	    SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
4320 # endif
4321 	}
4322 	si = &SCRIPT_ITEM(current_SID);
4323 	si->sn_name = fname_exp;
4324 	fname_exp = NULL;
4325 # ifdef UNIX
4326 	if (stat_ok)
4327 	{
4328 	    si->sn_dev_valid = TRUE;
4329 	    si->sn_dev = st.st_dev;
4330 	    si->sn_ino = st.st_ino;
4331 	}
4332 	else
4333 	    si->sn_dev_valid = FALSE;
4334 # endif
4335 
4336 	/* Allocate the local script variables to use for this script. */
4337 	new_script_vars(current_SID);
4338     }
4339 
4340 # ifdef FEAT_PROFILE
4341     if (do_profiling == PROF_YES)
4342     {
4343 	int	forceit;
4344 
4345 	/* Check if we do profiling for this script. */
4346 	if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit))
4347 	{
4348 	    script_do_profile(si);
4349 	    si->sn_pr_force = forceit;
4350 	}
4351 	if (si->sn_prof_on)
4352 	{
4353 	    ++si->sn_pr_count;
4354 	    profile_start(&si->sn_pr_start);
4355 	    profile_zero(&si->sn_pr_children);
4356 	}
4357     }
4358 # endif
4359 #endif
4360 
4361     /*
4362      * Call do_cmdline, which will call getsourceline() to get the lines.
4363      */
4364     do_cmdline(firstline, getsourceline, (void *)&cookie,
4365 				     DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
4366     retval = OK;
4367 
4368 #ifdef FEAT_PROFILE
4369     if (do_profiling == PROF_YES)
4370     {
4371 	/* Get "si" again, "script_items" may have been reallocated. */
4372 	si = &SCRIPT_ITEM(current_SID);
4373 	if (si->sn_prof_on)
4374 	{
4375 	    profile_end(&si->sn_pr_start);
4376 	    profile_sub_wait(&wait_start, &si->sn_pr_start);
4377 	    profile_add(&si->sn_pr_total, &si->sn_pr_start);
4378 	    profile_self(&si->sn_pr_self, &si->sn_pr_start,
4379 							 &si->sn_pr_children);
4380 	}
4381     }
4382 #endif
4383 
4384     if (got_int)
4385 	EMSG(_(e_interr));
4386     sourcing_name = save_sourcing_name;
4387     sourcing_lnum = save_sourcing_lnum;
4388     if (p_verbose > 1)
4389     {
4390 	verbose_enter();
4391 	smsg((char_u *)_("finished sourcing %s"), fname);
4392 	if (sourcing_name != NULL)
4393 	    smsg((char_u *)_("continuing in %s"), sourcing_name);
4394 	verbose_leave();
4395     }
4396 #ifdef STARTUPTIME
4397     if (time_fd != NULL)
4398     {
4399 	vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
4400 	time_msg((char *)IObuff, &tv_start);
4401 	time_pop(&tv_rel);
4402     }
4403 #endif
4404 
4405 #ifdef FEAT_EVAL
4406     /*
4407      * After a "finish" in debug mode, need to break at first command of next
4408      * sourced file.
4409      */
4410     if (save_debug_break_level > ex_nesting_level
4411 	    && debug_break_level == ex_nesting_level)
4412 	++debug_break_level;
4413 #endif
4414 
4415 #ifdef FEAT_EVAL
4416 almosttheend:
4417     current_SID = save_current_SID;
4418     restore_funccal(save_funccalp);
4419 # ifdef FEAT_PROFILE
4420     if (do_profiling == PROF_YES)
4421 	prof_child_exit(&wait_start);		/* leaving a child now */
4422 # endif
4423 #endif
4424     fclose(cookie.fp);
4425     vim_free(cookie.nextline);
4426     vim_free(firstline);
4427 #ifdef FEAT_MBYTE
4428     convert_setup(&cookie.conv, NULL, NULL);
4429 #endif
4430 
4431 theend:
4432     vim_free(fname_exp);
4433     return retval;
4434 }
4435 
4436 #if defined(FEAT_EVAL) || defined(PROTO)
4437 
4438 /*
4439  * ":scriptnames"
4440  */
4441     void
4442 ex_scriptnames(exarg_T *eap UNUSED)
4443 {
4444     int i;
4445 
4446     for (i = 1; i <= script_items.ga_len && !got_int; ++i)
4447 	if (SCRIPT_ITEM(i).sn_name != NULL)
4448 	{
4449 	    home_replace(NULL, SCRIPT_ITEM(i).sn_name,
4450 						    NameBuff, MAXPATHL, TRUE);
4451 	    smsg((char_u *)"%3d: %s", i, NameBuff);
4452 	}
4453 }
4454 
4455 # if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
4456 /*
4457  * Fix slashes in the list of script names for 'shellslash'.
4458  */
4459     void
4460 scriptnames_slash_adjust(void)
4461 {
4462     int i;
4463 
4464     for (i = 1; i <= script_items.ga_len; ++i)
4465 	if (SCRIPT_ITEM(i).sn_name != NULL)
4466 	    slash_adjust(SCRIPT_ITEM(i).sn_name);
4467 }
4468 # endif
4469 
4470 /*
4471  * Get a pointer to a script name.  Used for ":verbose set".
4472  */
4473     char_u *
4474 get_scriptname(scid_T id)
4475 {
4476     if (id == SID_MODELINE)
4477 	return (char_u *)_("modeline");
4478     if (id == SID_CMDARG)
4479 	return (char_u *)_("--cmd argument");
4480     if (id == SID_CARG)
4481 	return (char_u *)_("-c argument");
4482     if (id == SID_ENV)
4483 	return (char_u *)_("environment variable");
4484     if (id == SID_ERROR)
4485 	return (char_u *)_("error handler");
4486     return SCRIPT_ITEM(id).sn_name;
4487 }
4488 
4489 # if defined(EXITFREE) || defined(PROTO)
4490     void
4491 free_scriptnames(void)
4492 {
4493     int			i;
4494 
4495     for (i = script_items.ga_len; i > 0; --i)
4496 	vim_free(SCRIPT_ITEM(i).sn_name);
4497     ga_clear(&script_items);
4498 }
4499 # endif
4500 
4501 #endif
4502 
4503 #if defined(USE_CR) || defined(PROTO)
4504 
4505 # if defined(__MSL__) && (__MSL__ >= 22)
4506 /*
4507  * Newer version of the Metrowerks library handle DOS and UNIX files
4508  * without help.
4509  * Test with earlier versions, MSL 2.2 is the library supplied with
4510  * Codewarrior Pro 2.
4511  */
4512     char *
4513 fgets_cr(char *s, int n, FILE *stream)
4514 {
4515     return fgets(s, n, stream);
4516 }
4517 # else
4518 /*
4519  * Version of fgets() which also works for lines ending in a <CR> only
4520  * (Macintosh format).
4521  * For older versions of the Metrowerks library.
4522  * At least CodeWarrior 9 needed this code.
4523  */
4524     char *
4525 fgets_cr(char *s, int n, FILE *stream)
4526 {
4527     int	c = 0;
4528     int char_read = 0;
4529 
4530     while (!feof(stream) && c != '\r' && c != '\n' && char_read < n - 1)
4531     {
4532 	c = fgetc(stream);
4533 	s[char_read++] = c;
4534 	/* If the file is in DOS format, we need to skip a NL after a CR.  I
4535 	 * thought it was the other way around, but this appears to work... */
4536 	if (c == '\n')
4537 	{
4538 	    c = fgetc(stream);
4539 	    if (c != '\r')
4540 		ungetc(c, stream);
4541 	}
4542     }
4543 
4544     s[char_read] = 0;
4545     if (char_read == 0)
4546 	return NULL;
4547 
4548     if (feof(stream) && char_read == 1)
4549 	return NULL;
4550 
4551     return s;
4552 }
4553 # endif
4554 #endif
4555 
4556 /*
4557  * Get one full line from a sourced file.
4558  * Called by do_cmdline() when it's called from do_source().
4559  *
4560  * Return a pointer to the line in allocated memory.
4561  * Return NULL for end-of-file or some error.
4562  */
4563     char_u *
4564 getsourceline(int c UNUSED, void *cookie, int indent UNUSED)
4565 {
4566     struct source_cookie *sp = (struct source_cookie *)cookie;
4567     char_u		*line;
4568     char_u		*p;
4569 
4570 #ifdef FEAT_EVAL
4571     /* If breakpoints have been added/deleted need to check for it. */
4572     if (sp->dbg_tick < debug_tick)
4573     {
4574 	sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
4575 	sp->dbg_tick = debug_tick;
4576     }
4577 # ifdef FEAT_PROFILE
4578     if (do_profiling == PROF_YES)
4579 	script_line_end();
4580 # endif
4581 #endif
4582     /*
4583      * Get current line.  If there is a read-ahead line, use it, otherwise get
4584      * one now.
4585      */
4586     if (sp->finished)
4587 	line = NULL;
4588     else if (sp->nextline == NULL)
4589 	line = get_one_sourceline(sp);
4590     else
4591     {
4592 	line = sp->nextline;
4593 	sp->nextline = NULL;
4594 	++sourcing_lnum;
4595     }
4596 #ifdef FEAT_PROFILE
4597     if (line != NULL && do_profiling == PROF_YES)
4598 	script_line_start();
4599 #endif
4600 
4601     /* Only concatenate lines starting with a \ when 'cpoptions' doesn't
4602      * contain the 'C' flag. */
4603     if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL))
4604     {
4605 	/* compensate for the one line read-ahead */
4606 	--sourcing_lnum;
4607 
4608 	/* Get the next line and concatenate it when it starts with a
4609 	 * backslash. We always need to read the next line, keep it in
4610 	 * sp->nextline. */
4611 	sp->nextline = get_one_sourceline(sp);
4612 	if (sp->nextline != NULL && *(p = skipwhite(sp->nextline)) == '\\')
4613 	{
4614 	    garray_T    ga;
4615 
4616 	    ga_init2(&ga, (int)sizeof(char_u), 400);
4617 	    ga_concat(&ga, line);
4618 	    ga_concat(&ga, p + 1);
4619 	    for (;;)
4620 	    {
4621 		vim_free(sp->nextline);
4622 		sp->nextline = get_one_sourceline(sp);
4623 		if (sp->nextline == NULL)
4624 		    break;
4625 		p = skipwhite(sp->nextline);
4626 		if (*p != '\\')
4627 		    break;
4628 		/* Adjust the growsize to the current length to speed up
4629 		 * concatenating many lines. */
4630 		if (ga.ga_len > 400)
4631 		{
4632 		    if (ga.ga_len > 8000)
4633 			ga.ga_growsize = 8000;
4634 		    else
4635 			ga.ga_growsize = ga.ga_len;
4636 		}
4637 		ga_concat(&ga, p + 1);
4638 	    }
4639 	    ga_append(&ga, NUL);
4640 	    vim_free(line);
4641 	    line = ga.ga_data;
4642 	}
4643     }
4644 
4645 #ifdef FEAT_MBYTE
4646     if (line != NULL && sp->conv.vc_type != CONV_NONE)
4647     {
4648 	char_u	*s;
4649 
4650 	/* Convert the encoding of the script line. */
4651 	s = string_convert(&sp->conv, line, NULL);
4652 	if (s != NULL)
4653 	{
4654 	    vim_free(line);
4655 	    line = s;
4656 	}
4657     }
4658 #endif
4659 
4660 #ifdef FEAT_EVAL
4661     /* Did we encounter a breakpoint? */
4662     if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
4663     {
4664 	dbg_breakpoint(sp->fname, sourcing_lnum);
4665 	/* Find next breakpoint. */
4666 	sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
4667 	sp->dbg_tick = debug_tick;
4668     }
4669 #endif
4670 
4671     return line;
4672 }
4673 
4674     static char_u *
4675 get_one_sourceline(struct source_cookie *sp)
4676 {
4677     garray_T		ga;
4678     int			len;
4679     int			c;
4680     char_u		*buf;
4681 #ifdef USE_CRNL
4682     int			has_cr;		/* CR-LF found */
4683 #endif
4684 #ifdef USE_CR
4685     char_u		*scan;
4686 #endif
4687     int			have_read = FALSE;
4688 
4689     /* use a growarray to store the sourced line */
4690     ga_init2(&ga, 1, 250);
4691 
4692     /*
4693      * Loop until there is a finished line (or end-of-file).
4694      */
4695     sourcing_lnum++;
4696     for (;;)
4697     {
4698 	/* make room to read at least 120 (more) characters */
4699 	if (ga_grow(&ga, 120) == FAIL)
4700 	    break;
4701 	buf = (char_u *)ga.ga_data;
4702 
4703 #ifdef USE_CR
4704 	if (sp->fileformat == EOL_MAC)
4705 	{
4706 	    if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
4707 							      sp->fp) == NULL)
4708 		break;
4709 	}
4710 	else
4711 #endif
4712 	    if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
4713 							      sp->fp) == NULL)
4714 		break;
4715 	len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
4716 #ifdef USE_CRNL
4717 	/* Ignore a trailing CTRL-Z, when in Dos mode.	Only recognize the
4718 	 * CTRL-Z by its own, or after a NL. */
4719 	if (	   (len == 1 || (len >= 2 && buf[len - 2] == '\n'))
4720 		&& sp->fileformat == EOL_DOS
4721 		&& buf[len - 1] == Ctrl_Z)
4722 	{
4723 	    buf[len - 1] = NUL;
4724 	    break;
4725 	}
4726 #endif
4727 
4728 #ifdef USE_CR
4729 	/* If the read doesn't stop on a new line, and there's
4730 	 * some CR then we assume a Mac format */
4731 	if (sp->fileformat == EOL_UNKNOWN)
4732 	{
4733 	    if (buf[len - 1] != '\n' && vim_strchr(buf, '\r') != NULL)
4734 		sp->fileformat = EOL_MAC;
4735 	    else
4736 		sp->fileformat = EOL_UNIX;
4737 	}
4738 
4739 	if (sp->fileformat == EOL_MAC)
4740 	{
4741 	    scan = vim_strchr(buf, '\r');
4742 
4743 	    if (scan != NULL)
4744 	    {
4745 		*scan = '\n';
4746 		if (*(scan + 1) != 0)
4747 		{
4748 		    *(scan + 1) = 0;
4749 		    fseek(sp->fp, (long)(scan - buf - len + 1), SEEK_CUR);
4750 		}
4751 	    }
4752 	    len = STRLEN(buf);
4753 	}
4754 #endif
4755 
4756 	have_read = TRUE;
4757 	ga.ga_len = len;
4758 
4759 	/* If the line was longer than the buffer, read more. */
4760 	if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
4761 	    continue;
4762 
4763 	if (len >= 1 && buf[len - 1] == '\n')	/* remove trailing NL */
4764 	{
4765 #ifdef USE_CRNL
4766 	    has_cr = (len >= 2 && buf[len - 2] == '\r');
4767 	    if (sp->fileformat == EOL_UNKNOWN)
4768 	    {
4769 		if (has_cr)
4770 		    sp->fileformat = EOL_DOS;
4771 		else
4772 		    sp->fileformat = EOL_UNIX;
4773 	    }
4774 
4775 	    if (sp->fileformat == EOL_DOS)
4776 	    {
4777 		if (has_cr)	    /* replace trailing CR */
4778 		{
4779 		    buf[len - 2] = '\n';
4780 		    --len;
4781 		    --ga.ga_len;
4782 		}
4783 		else	    /* lines like ":map xx yy^M" will have failed */
4784 		{
4785 		    if (!sp->error)
4786 		    {
4787 			msg_source(HL_ATTR(HLF_W));
4788 			EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
4789 		    }
4790 		    sp->error = TRUE;
4791 		    sp->fileformat = EOL_UNIX;
4792 		}
4793 	    }
4794 #endif
4795 	    /* The '\n' is escaped if there is an odd number of ^V's just
4796 	     * before it, first set "c" just before the 'V's and then check
4797 	     * len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo */
4798 	    for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--)
4799 		;
4800 	    if ((len & 1) != (c & 1))	/* escaped NL, read more */
4801 	    {
4802 		sourcing_lnum++;
4803 		continue;
4804 	    }
4805 
4806 	    buf[len - 1] = NUL;		/* remove the NL */
4807 	}
4808 
4809 	/*
4810 	 * Check for ^C here now and then, so recursive :so can be broken.
4811 	 */
4812 	line_breakcheck();
4813 	break;
4814     }
4815 
4816     if (have_read)
4817 	return (char_u *)ga.ga_data;
4818 
4819     vim_free(ga.ga_data);
4820     return NULL;
4821 }
4822 
4823 #if defined(FEAT_PROFILE) || defined(PROTO)
4824 /*
4825  * Called when starting to read a script line.
4826  * "sourcing_lnum" must be correct!
4827  * When skipping lines it may not actually be executed, but we won't find out
4828  * until later and we need to store the time now.
4829  */
4830     void
4831 script_line_start(void)
4832 {
4833     scriptitem_T    *si;
4834     sn_prl_T	    *pp;
4835 
4836     if (current_SID <= 0 || current_SID > script_items.ga_len)
4837 	return;
4838     si = &SCRIPT_ITEM(current_SID);
4839     if (si->sn_prof_on && sourcing_lnum >= 1)
4840     {
4841 	/* Grow the array before starting the timer, so that the time spent
4842 	 * here isn't counted. */
4843 	(void)ga_grow(&si->sn_prl_ga, (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
4844 	si->sn_prl_idx = sourcing_lnum - 1;
4845 	while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
4846 		&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
4847 	{
4848 	    /* Zero counters for a line that was not used before. */
4849 	    pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len);
4850 	    pp->snp_count = 0;
4851 	    profile_zero(&pp->sn_prl_total);
4852 	    profile_zero(&pp->sn_prl_self);
4853 	    ++si->sn_prl_ga.ga_len;
4854 	}
4855 	si->sn_prl_execed = FALSE;
4856 	profile_start(&si->sn_prl_start);
4857 	profile_zero(&si->sn_prl_children);
4858 	profile_get_wait(&si->sn_prl_wait);
4859     }
4860 }
4861 
4862 /*
4863  * Called when actually executing a function line.
4864  */
4865     void
4866 script_line_exec(void)
4867 {
4868     scriptitem_T    *si;
4869 
4870     if (current_SID <= 0 || current_SID > script_items.ga_len)
4871 	return;
4872     si = &SCRIPT_ITEM(current_SID);
4873     if (si->sn_prof_on && si->sn_prl_idx >= 0)
4874 	si->sn_prl_execed = TRUE;
4875 }
4876 
4877 /*
4878  * Called when done with a function line.
4879  */
4880     void
4881 script_line_end(void)
4882 {
4883     scriptitem_T    *si;
4884     sn_prl_T	    *pp;
4885 
4886     if (current_SID <= 0 || current_SID > script_items.ga_len)
4887 	return;
4888     si = &SCRIPT_ITEM(current_SID);
4889     if (si->sn_prof_on && si->sn_prl_idx >= 0
4890 				     && si->sn_prl_idx < si->sn_prl_ga.ga_len)
4891     {
4892 	if (si->sn_prl_execed)
4893 	{
4894 	    pp = &PRL_ITEM(si, si->sn_prl_idx);
4895 	    ++pp->snp_count;
4896 	    profile_end(&si->sn_prl_start);
4897 	    profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start);
4898 	    profile_add(&pp->sn_prl_total, &si->sn_prl_start);
4899 	    profile_self(&pp->sn_prl_self, &si->sn_prl_start,
4900 							&si->sn_prl_children);
4901 	}
4902 	si->sn_prl_idx = -1;
4903     }
4904 }
4905 #endif
4906 
4907 /*
4908  * ":scriptencoding": Set encoding conversion for a sourced script.
4909  * Without the multi-byte feature it's simply ignored.
4910  */
4911     void
4912 ex_scriptencoding(exarg_T *eap UNUSED)
4913 {
4914 #ifdef FEAT_MBYTE
4915     struct source_cookie	*sp;
4916     char_u			*name;
4917 
4918     if (!getline_equal(eap->getline, eap->cookie, getsourceline))
4919     {
4920 	EMSG(_("E167: :scriptencoding used outside of a sourced file"));
4921 	return;
4922     }
4923 
4924     if (*eap->arg != NUL)
4925     {
4926 	name = enc_canonize(eap->arg);
4927 	if (name == NULL)	/* out of memory */
4928 	    return;
4929     }
4930     else
4931 	name = eap->arg;
4932 
4933     /* Setup for conversion from the specified encoding to 'encoding'. */
4934     sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie);
4935     convert_setup(&sp->conv, name, p_enc);
4936 
4937     if (name != eap->arg)
4938 	vim_free(name);
4939 #endif
4940 }
4941 
4942 #if defined(FEAT_EVAL) || defined(PROTO)
4943 /*
4944  * ":finish": Mark a sourced file as finished.
4945  */
4946     void
4947 ex_finish(exarg_T *eap)
4948 {
4949     if (getline_equal(eap->getline, eap->cookie, getsourceline))
4950 	do_finish(eap, FALSE);
4951     else
4952 	EMSG(_("E168: :finish used outside of a sourced file"));
4953 }
4954 
4955 /*
4956  * Mark a sourced file as finished.  Possibly makes the ":finish" pending.
4957  * Also called for a pending finish at the ":endtry" or after returning from
4958  * an extra do_cmdline().  "reanimate" is used in the latter case.
4959  */
4960     void
4961 do_finish(exarg_T *eap, int reanimate)
4962 {
4963     int		idx;
4964 
4965     if (reanimate)
4966 	((struct source_cookie *)getline_cookie(eap->getline,
4967 					      eap->cookie))->finished = FALSE;
4968 
4969     /*
4970      * Cleanup (and inactivate) conditionals, but stop when a try conditional
4971      * not in its finally clause (which then is to be executed next) is found.
4972      * In this case, make the ":finish" pending for execution at the ":endtry".
4973      * Otherwise, finish normally.
4974      */
4975     idx = cleanup_conditionals(eap->cstack, 0, TRUE);
4976     if (idx >= 0)
4977     {
4978 	eap->cstack->cs_pending[idx] = CSTP_FINISH;
4979 	report_make_pending(CSTP_FINISH, NULL);
4980     }
4981     else
4982 	((struct source_cookie *)getline_cookie(eap->getline,
4983 					       eap->cookie))->finished = TRUE;
4984 }
4985 
4986 
4987 /*
4988  * Return TRUE when a sourced file had the ":finish" command: Don't give error
4989  * message for missing ":endif".
4990  * Return FALSE when not sourcing a file.
4991  */
4992     int
4993 source_finished(
4994     char_u	*(*fgetline)(int, void *, int),
4995     void	*cookie)
4996 {
4997     return (getline_equal(fgetline, cookie, getsourceline)
4998 	    && ((struct source_cookie *)getline_cookie(
4999 						fgetline, cookie))->finished);
5000 }
5001 #endif
5002 
5003 #if defined(FEAT_LISTCMDS) || defined(PROTO)
5004 /*
5005  * ":checktime [buffer]"
5006  */
5007     void
5008 ex_checktime(exarg_T *eap)
5009 {
5010     buf_T	*buf;
5011     int		save_no_check_timestamps = no_check_timestamps;
5012 
5013     no_check_timestamps = 0;
5014     if (eap->addr_count == 0)	/* default is all buffers */
5015 	check_timestamps(FALSE);
5016     else
5017     {
5018 	buf = buflist_findnr((int)eap->line2);
5019 	if (buf != NULL)	/* cannot happen? */
5020 	    (void)buf_check_timestamp(buf, FALSE);
5021     }
5022     no_check_timestamps = save_no_check_timestamps;
5023 }
5024 #endif
5025 
5026 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
5027 	&& (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG))
5028 # define HAVE_GET_LOCALE_VAL
5029 static char_u *get_locale_val(int what);
5030 
5031     static char_u *
5032 get_locale_val(int what)
5033 {
5034     char_u	*loc;
5035 
5036     /* Obtain the locale value from the libraries. */
5037     loc = (char_u *)setlocale(what, NULL);
5038 
5039 # ifdef WIN32
5040     if (loc != NULL)
5041     {
5042 	char_u	*p;
5043 
5044 	/* setocale() returns something like "LC_COLLATE=<name>;LC_..." when
5045 	 * one of the values (e.g., LC_CTYPE) differs. */
5046 	p = vim_strchr(loc, '=');
5047 	if (p != NULL)
5048 	{
5049 	    loc = ++p;
5050 	    while (*p != NUL)	/* remove trailing newline */
5051 	    {
5052 		if (*p < ' ' || *p == ';')
5053 		{
5054 		    *p = NUL;
5055 		    break;
5056 		}
5057 		++p;
5058 	    }
5059 	}
5060     }
5061 # endif
5062 
5063     return loc;
5064 }
5065 #endif
5066 
5067 
5068 #ifdef WIN32
5069 /*
5070  * On MS-Windows locale names are strings like "German_Germany.1252", but
5071  * gettext expects "de".  Try to translate one into another here for a few
5072  * supported languages.
5073  */
5074     static char_u *
5075 gettext_lang(char_u *name)
5076 {
5077     int		i;
5078     static char *(mtable[]) = {
5079 			"afrikaans",	"af",
5080 			"czech",	"cs",
5081 			"dutch",	"nl",
5082 			"german",	"de",
5083 			"english_united kingdom", "en_GB",
5084 			"spanish",	"es",
5085 			"french",	"fr",
5086 			"italian",	"it",
5087 			"japanese",	"ja",
5088 			"korean",	"ko",
5089 			"norwegian",	"no",
5090 			"polish",	"pl",
5091 			"russian",	"ru",
5092 			"slovak",	"sk",
5093 			"swedish",	"sv",
5094 			"ukrainian",	"uk",
5095 			"chinese_china", "zh_CN",
5096 			"chinese_taiwan", "zh_TW",
5097 			NULL};
5098 
5099     for (i = 0; mtable[i] != NULL; i += 2)
5100 	if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0)
5101 	    return (char_u *)mtable[i + 1];
5102     return name;
5103 }
5104 #endif
5105 
5106 #if defined(FEAT_MULTI_LANG) || defined(PROTO)
5107 /*
5108  * Obtain the current messages language.  Used to set the default for
5109  * 'helplang'.  May return NULL or an empty string.
5110  */
5111     char_u *
5112 get_mess_lang(void)
5113 {
5114     char_u *p;
5115 
5116 # ifdef HAVE_GET_LOCALE_VAL
5117 #  if defined(LC_MESSAGES)
5118     p = get_locale_val(LC_MESSAGES);
5119 #  else
5120     /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
5121      * may be set to the LCID number.  LC_COLLATE is the best guess, LC_TIME
5122      * and LC_MONETARY may be set differently for a Japanese working in the
5123      * US. */
5124     p = get_locale_val(LC_COLLATE);
5125 #  endif
5126 # else
5127     p = mch_getenv((char_u *)"LC_ALL");
5128     if (p == NULL || *p == NUL)
5129     {
5130 	p = mch_getenv((char_u *)"LC_MESSAGES");
5131 	if (p == NULL || *p == NUL)
5132 	    p = mch_getenv((char_u *)"LANG");
5133     }
5134 # endif
5135 # ifdef WIN32
5136     p = gettext_lang(p);
5137 # endif
5138     return p;
5139 }
5140 #endif
5141 
5142 /* Complicated #if; matches with where get_mess_env() is used below. */
5143 #if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
5144 	    && defined(LC_MESSAGES))) \
5145 	|| ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
5146 		&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) \
5147 		&& !defined(LC_MESSAGES))
5148 static char_u *get_mess_env(void);
5149 
5150 /*
5151  * Get the language used for messages from the environment.
5152  */
5153     static char_u *
5154 get_mess_env(void)
5155 {
5156     char_u	*p;
5157 
5158     p = mch_getenv((char_u *)"LC_ALL");
5159     if (p == NULL || *p == NUL)
5160     {
5161 	p = mch_getenv((char_u *)"LC_MESSAGES");
5162 	if (p == NULL || *p == NUL)
5163 	{
5164 	    p = mch_getenv((char_u *)"LANG");
5165 	    if (p != NULL && VIM_ISDIGIT(*p))
5166 		p = NULL;		/* ignore something like "1043" */
5167 # ifdef HAVE_GET_LOCALE_VAL
5168 	    if (p == NULL || *p == NUL)
5169 		p = get_locale_val(LC_CTYPE);
5170 # endif
5171 	}
5172     }
5173     return p;
5174 }
5175 #endif
5176 
5177 #if defined(FEAT_EVAL) || defined(PROTO)
5178 
5179 /*
5180  * Set the "v:lang" variable according to the current locale setting.
5181  * Also do "v:lc_time"and "v:ctype".
5182  */
5183     void
5184 set_lang_var(void)
5185 {
5186     char_u	*loc;
5187 
5188 # ifdef HAVE_GET_LOCALE_VAL
5189     loc = get_locale_val(LC_CTYPE);
5190 # else
5191     /* setlocale() not supported: use the default value */
5192     loc = (char_u *)"C";
5193 # endif
5194     set_vim_var_string(VV_CTYPE, loc, -1);
5195 
5196     /* When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
5197      * back to LC_CTYPE if it's empty. */
5198 # if defined(HAVE_GET_LOCALE_VAL) && defined(LC_MESSAGES)
5199     loc = get_locale_val(LC_MESSAGES);
5200 # else
5201     loc = get_mess_env();
5202 # endif
5203     set_vim_var_string(VV_LANG, loc, -1);
5204 
5205 # ifdef HAVE_GET_LOCALE_VAL
5206     loc = get_locale_val(LC_TIME);
5207 # endif
5208     set_vim_var_string(VV_LC_TIME, loc, -1);
5209 }
5210 #endif
5211 
5212 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
5213 	&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
5214 /*
5215  * ":language":  Set the language (locale).
5216  */
5217     void
5218 ex_language(exarg_T *eap)
5219 {
5220     char	*loc;
5221     char_u	*p;
5222     char_u	*name;
5223     int		what = LC_ALL;
5224     char	*whatstr = "";
5225 #ifdef LC_MESSAGES
5226 # define VIM_LC_MESSAGES LC_MESSAGES
5227 #else
5228 # define VIM_LC_MESSAGES 6789
5229 #endif
5230 
5231     name = eap->arg;
5232 
5233     /* Check for "messages {name}", "ctype {name}" or "time {name}" argument.
5234      * Allow abbreviation, but require at least 3 characters to avoid
5235      * confusion with a two letter language name "me" or "ct". */
5236     p = skiptowhite(eap->arg);
5237     if ((*p == NUL || VIM_ISWHITE(*p)) && p - eap->arg >= 3)
5238     {
5239 	if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0)
5240 	{
5241 	    what = VIM_LC_MESSAGES;
5242 	    name = skipwhite(p);
5243 	    whatstr = "messages ";
5244 	}
5245 	else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0)
5246 	{
5247 	    what = LC_CTYPE;
5248 	    name = skipwhite(p);
5249 	    whatstr = "ctype ";
5250 	}
5251 	else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0)
5252 	{
5253 	    what = LC_TIME;
5254 	    name = skipwhite(p);
5255 	    whatstr = "time ";
5256 	}
5257     }
5258 
5259     if (*name == NUL)
5260     {
5261 #ifndef LC_MESSAGES
5262 	if (what == VIM_LC_MESSAGES)
5263 	    p = get_mess_env();
5264 	else
5265 #endif
5266 	    p = (char_u *)setlocale(what, NULL);
5267 	if (p == NULL || *p == NUL)
5268 	    p = (char_u *)"Unknown";
5269 	smsg((char_u *)_("Current %slanguage: \"%s\""), whatstr, p);
5270     }
5271     else
5272     {
5273 #ifndef LC_MESSAGES
5274 	if (what == VIM_LC_MESSAGES)
5275 	    loc = "";
5276 	else
5277 #endif
5278 	{
5279 	    loc = setlocale(what, (char *)name);
5280 #if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
5281 	    /* Make sure strtod() uses a decimal point, not a comma. */
5282 	    setlocale(LC_NUMERIC, "C");
5283 #endif
5284 	}
5285 	if (loc == NULL)
5286 	    EMSG2(_("E197: Cannot set language to \"%s\""), name);
5287 	else
5288 	{
5289 #ifdef HAVE_NL_MSG_CAT_CNTR
5290 	    /* Need to do this for GNU gettext, otherwise cached translations
5291 	     * will be used again. */
5292 	    extern int _nl_msg_cat_cntr;
5293 
5294 	    ++_nl_msg_cat_cntr;
5295 #endif
5296 	    /* Reset $LC_ALL, otherwise it would overrule everything. */
5297 	    vim_setenv((char_u *)"LC_ALL", (char_u *)"");
5298 
5299 	    if (what != LC_TIME)
5300 	    {
5301 		/* Tell gettext() what to translate to.  It apparently doesn't
5302 		 * use the currently effective locale.  Also do this when
5303 		 * FEAT_GETTEXT isn't defined, so that shell commands use this
5304 		 * value. */
5305 		if (what == LC_ALL)
5306 		{
5307 		    vim_setenv((char_u *)"LANG", name);
5308 
5309 		    /* Clear $LANGUAGE because GNU gettext uses it. */
5310 		    vim_setenv((char_u *)"LANGUAGE", (char_u *)"");
5311 # ifdef WIN32
5312 		    /* Apparently MS-Windows printf() may cause a crash when
5313 		     * we give it 8-bit text while it's expecting text in the
5314 		     * current locale.  This call avoids that. */
5315 		    setlocale(LC_CTYPE, "C");
5316 # endif
5317 		}
5318 		if (what != LC_CTYPE)
5319 		{
5320 		    char_u	*mname;
5321 #ifdef WIN32
5322 		    mname = gettext_lang(name);
5323 #else
5324 		    mname = name;
5325 #endif
5326 		    vim_setenv((char_u *)"LC_MESSAGES", mname);
5327 #ifdef FEAT_MULTI_LANG
5328 		    set_helplang_default(mname);
5329 #endif
5330 		}
5331 	    }
5332 
5333 # ifdef FEAT_EVAL
5334 	    /* Set v:lang, v:lc_time and v:ctype to the final result. */
5335 	    set_lang_var();
5336 # endif
5337 # ifdef FEAT_TITLE
5338 	    maketitle();
5339 # endif
5340 	}
5341     }
5342 }
5343 
5344 # if defined(FEAT_CMDL_COMPL) || defined(PROTO)
5345 
5346 static char_u	**locales = NULL;	/* Array of all available locales */
5347 
5348 #  ifndef WIN32
5349 static int	did_init_locales = FALSE;
5350 
5351 /* Return an array of strings for all available locales + NULL for the
5352  * last element.  Return NULL in case of error. */
5353     static char_u **
5354 find_locales(void)
5355 {
5356     garray_T	locales_ga;
5357     char_u	*loc;
5358 
5359     /* Find all available locales by running command "locale -a".  If this
5360      * doesn't work we won't have completion. */
5361     char_u *locale_a = get_cmd_output((char_u *)"locale -a",
5362 						    NULL, SHELL_SILENT, NULL);
5363     if (locale_a == NULL)
5364 	return NULL;
5365     ga_init2(&locales_ga, sizeof(char_u *), 20);
5366 
5367     /* Transform locale_a string where each locale is separated by "\n"
5368      * into an array of locale strings. */
5369     loc = (char_u *)strtok((char *)locale_a, "\n");
5370 
5371     while (loc != NULL)
5372     {
5373 	if (ga_grow(&locales_ga, 1) == FAIL)
5374 	    break;
5375 	loc = vim_strsave(loc);
5376 	if (loc == NULL)
5377 	    break;
5378 
5379 	((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc;
5380 	loc = (char_u *)strtok(NULL, "\n");
5381     }
5382     vim_free(locale_a);
5383     if (ga_grow(&locales_ga, 1) == FAIL)
5384     {
5385 	ga_clear(&locales_ga);
5386 	return NULL;
5387     }
5388     ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
5389     return (char_u **)locales_ga.ga_data;
5390 }
5391 #  endif
5392 
5393 /*
5394  * Lazy initialization of all available locales.
5395  */
5396     static void
5397 init_locales(void)
5398 {
5399 #  ifndef WIN32
5400     if (!did_init_locales)
5401     {
5402 	did_init_locales = TRUE;
5403 	locales = find_locales();
5404     }
5405 #  endif
5406 }
5407 
5408 #  if defined(EXITFREE) || defined(PROTO)
5409     void
5410 free_locales(void)
5411 {
5412     int			i;
5413     if (locales != NULL)
5414     {
5415 	for (i = 0; locales[i] != NULL; i++)
5416 	    vim_free(locales[i]);
5417 	vim_free(locales);
5418 	locales = NULL;
5419     }
5420 }
5421 #  endif
5422 
5423 /*
5424  * Function given to ExpandGeneric() to obtain the possible arguments of the
5425  * ":language" command.
5426  */
5427     char_u *
5428 get_lang_arg(expand_T *xp UNUSED, int idx)
5429 {
5430     if (idx == 0)
5431 	return (char_u *)"messages";
5432     if (idx == 1)
5433 	return (char_u *)"ctype";
5434     if (idx == 2)
5435 	return (char_u *)"time";
5436 
5437     init_locales();
5438     if (locales == NULL)
5439 	return NULL;
5440     return locales[idx - 3];
5441 }
5442 
5443 /*
5444  * Function given to ExpandGeneric() to obtain the available locales.
5445  */
5446     char_u *
5447 get_locales(expand_T *xp UNUSED, int idx)
5448 {
5449     init_locales();
5450     if (locales == NULL)
5451 	return NULL;
5452     return locales[idx];
5453 }
5454 # endif
5455 
5456 #endif
5457