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