xref: /vim-8.2.3635/src/ex_cmds2.c (revision 899dddf8)
1 /* vi:set ts=8 sts=4 sw=4:
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 #if defined(WIN32) && defined(FEAT_CSCOPE)
15 # include "vimio.h"
16 #endif
17 
18 #include "vim.h"
19 
20 #if defined(WIN32) && defined(FEAT_CSCOPE)
21 # include <fcntl.h>
22 #endif
23 
24 #include "version.h"
25 
26 static void	cmd_source __ARGS((char_u *fname, exarg_T *eap));
27 
28 #ifdef FEAT_EVAL
29 /* Growarray to store info about already sourced scripts.
30  * For Unix also store the dev/ino, so that we don't have to stat() each
31  * script when going through the list. */
32 typedef struct scriptitem_S
33 {
34     char_u	*sn_name;
35 # ifdef UNIX
36     int		sn_dev;
37     ino_t	sn_ino;
38 # endif
39 # ifdef FEAT_PROFILE
40     int		sn_prof_on;	/* TRUE when script is/was profiled */
41     int		sn_pr_force;	/* forceit: profile functions in this script */
42     proftime_T	sn_pr_child;	/* time set when going into first child */
43     int		sn_pr_nest;	/* nesting for sn_pr_child */
44     /* profiling the script as a whole */
45     int		sn_pr_count;	/* nr of times sourced */
46     proftime_T	sn_pr_total;	/* time spend in script + children */
47     proftime_T	sn_pr_self;	/* time spend in script itself */
48     proftime_T	sn_pr_start;	/* time at script start */
49     proftime_T	sn_pr_children; /* time in children after script start */
50     /* profiling the script per line */
51     garray_T	sn_prl_ga;	/* things stored for every line */
52     proftime_T	sn_prl_start;	/* start time for current line */
53     proftime_T	sn_prl_children; /* time spent in children for this line */
54     proftime_T	sn_prl_wait;	/* wait start time for current line */
55     int		sn_prl_idx;	/* index of line being timed; -1 if none */
56     int		sn_prl_execed;	/* line being timed was executed */
57 # endif
58 } scriptitem_T;
59 
60 static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL};
61 #define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
62 
63 # ifdef FEAT_PROFILE
64 /* Struct used in sn_prl_ga for every line of a script. */
65 typedef struct sn_prl_S
66 {
67     int		snp_count;	/* nr of times line was executed */
68     proftime_T	sn_prl_total;	/* time spend in a line + children */
69     proftime_T	sn_prl_self;	/* time spend in a line itself */
70 } sn_prl_T;
71 
72 #  define PRL_ITEM(si, idx)	(((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
73 # endif
74 #endif
75 
76 #if defined(FEAT_EVAL) || defined(PROTO)
77 static int debug_greedy = FALSE;	/* batch mode debugging: don't save
78 					   and restore typeahead. */
79 
80 /*
81  * do_debug(): Debug mode.
82  * Repeatedly get Ex commands, until told to continue normal execution.
83  */
84     void
85 do_debug(cmd)
86     char_u	*cmd;
87 {
88     int		save_msg_scroll = msg_scroll;
89     int		save_State = State;
90     int		save_did_emsg = did_emsg;
91     int		save_cmd_silent = cmd_silent;
92     int		save_msg_silent = msg_silent;
93     int		save_emsg_silent = emsg_silent;
94     int		save_redir_off = redir_off;
95     tasave_T	typeaheadbuf;
96 # ifdef FEAT_EX_EXTRA
97     int		save_ex_normal_busy;
98 # endif
99     int		n;
100     char_u	*cmdline = NULL;
101     char_u	*p;
102     char	*tail = NULL;
103     static int	last_cmd = 0;
104 #define CMD_CONT	1
105 #define CMD_NEXT	2
106 #define CMD_STEP	3
107 #define CMD_FINISH	4
108 #define CMD_QUIT	5
109 #define CMD_INTERRUPT	6
110 
111 #ifdef ALWAYS_USE_GUI
112     /* Can't do this when there is no terminal for input/output. */
113     if (!gui.in_use)
114     {
115 	/* Break as soon as possible. */
116 	debug_break_level = 9999;
117 	return;
118     }
119 #endif
120 
121     /* Make sure we are in raw mode and start termcap mode.  Might have side
122      * effects... */
123     settmode(TMODE_RAW);
124     starttermcap();
125 
126     ++RedrawingDisabled;	/* don't redisplay the window */
127     ++no_wait_return;		/* don't wait for return */
128     did_emsg = FALSE;		/* don't use error from debugged stuff */
129     cmd_silent = FALSE;		/* display commands */
130     msg_silent = FALSE;		/* display messages */
131     emsg_silent = FALSE;	/* display error messages */
132     redir_off = TRUE;		/* don't redirect debug commands */
133 
134     State = NORMAL;
135 #ifdef FEAT_SNIFF
136     want_sniff_request = 0;    /* No K_SNIFF wanted */
137 #endif
138 
139     if (!debug_did_msg)
140 	MSG(_("Entering Debug mode.  Type \"cont\" to continue."));
141     if (sourcing_name != NULL)
142 	msg(sourcing_name);
143     if (sourcing_lnum != 0)
144 	smsg((char_u *)_("line %ld: %s"), (long)sourcing_lnum, cmd);
145     else
146 	smsg((char_u *)_("cmd: %s"), cmd);
147 
148     /*
149      * Repeat getting a command and executing it.
150      */
151     for (;;)
152     {
153 	msg_scroll = TRUE;
154 	need_wait_return = FALSE;
155 #ifdef FEAT_SNIFF
156 	ProcessSniffRequests();
157 #endif
158 	/* Save the current typeahead buffer and replace it with an empty one.
159 	 * This makes sure we get input from the user here and don't interfere
160 	 * with the commands being executed.  Reset "ex_normal_busy" to avoid
161 	 * the side effects of using ":normal". Save the stuff buffer and make
162 	 * it empty. */
163 # ifdef FEAT_EX_EXTRA
164 	save_ex_normal_busy = ex_normal_busy;
165 	ex_normal_busy = 0;
166 # endif
167 	if (!debug_greedy)
168 	    save_typeahead(&typeaheadbuf);
169 
170 	cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
171 
172 	if (!debug_greedy)
173 	    restore_typeahead(&typeaheadbuf);
174 # ifdef FEAT_EX_EXTRA
175 	ex_normal_busy = save_ex_normal_busy;
176 # endif
177 
178 	cmdline_row = msg_row;
179 	if (cmdline != NULL)
180 	{
181 	    /* If this is a debug command, set "last_cmd".
182 	     * If not, reset "last_cmd".
183 	     * For a blank line use previous command. */
184 	    p = skipwhite(cmdline);
185 	    if (*p != NUL)
186 	    {
187 		switch (*p)
188 		{
189 		    case 'c': last_cmd = CMD_CONT;
190 			      tail = "ont";
191 			      break;
192 		    case 'n': last_cmd = CMD_NEXT;
193 			      tail = "ext";
194 			      break;
195 		    case 's': last_cmd = CMD_STEP;
196 			      tail = "tep";
197 			      break;
198 		    case 'f': last_cmd = CMD_FINISH;
199 			      tail = "inish";
200 			      break;
201 		    case 'q': last_cmd = CMD_QUIT;
202 			      tail = "uit";
203 			      break;
204 		    case 'i': last_cmd = CMD_INTERRUPT;
205 			      tail = "nterrupt";
206 			      break;
207 		    default: last_cmd = 0;
208 		}
209 		if (last_cmd != 0)
210 		{
211 		    /* Check that the tail matches. */
212 		    ++p;
213 		    while (*p != NUL && *p == *tail)
214 		    {
215 			++p;
216 			++tail;
217 		    }
218 		    if (ASCII_ISALPHA(*p))
219 			last_cmd = 0;
220 		}
221 	    }
222 
223 	    if (last_cmd != 0)
224 	    {
225 		/* Execute debug command: decided where to break next and
226 		 * return. */
227 		switch (last_cmd)
228 		{
229 		    case CMD_CONT:
230 			debug_break_level = -1;
231 			break;
232 		    case CMD_NEXT:
233 			debug_break_level = ex_nesting_level;
234 			break;
235 		    case CMD_STEP:
236 			debug_break_level = 9999;
237 			break;
238 		    case CMD_FINISH:
239 			debug_break_level = ex_nesting_level - 1;
240 			break;
241 		    case CMD_QUIT:
242 			got_int = TRUE;
243 			debug_break_level = -1;
244 			break;
245 		    case CMD_INTERRUPT:
246 			got_int = TRUE;
247 			debug_break_level = 9999;
248 			/* Do not repeat ">interrupt" cmd, continue stepping. */
249 			last_cmd = CMD_STEP;
250 			break;
251 		}
252 		break;
253 	    }
254 
255 	    /* don't debug this command */
256 	    n = debug_break_level;
257 	    debug_break_level = -1;
258 	    (void)do_cmdline(cmdline, getexline, NULL,
259 						DOCMD_VERBOSE|DOCMD_EXCRESET);
260 	    debug_break_level = n;
261 
262 	    vim_free(cmdline);
263 	}
264 	lines_left = Rows - 1;
265     }
266     vim_free(cmdline);
267 
268     --RedrawingDisabled;
269     --no_wait_return;
270     redraw_all_later(NOT_VALID);
271     need_wait_return = FALSE;
272     msg_scroll = save_msg_scroll;
273     lines_left = Rows - 1;
274     State = save_State;
275     did_emsg = save_did_emsg;
276     cmd_silent = save_cmd_silent;
277     msg_silent = save_msg_silent;
278     emsg_silent = save_emsg_silent;
279     redir_off = save_redir_off;
280 
281     /* Only print the message again when typing a command before coming back
282      * here. */
283     debug_did_msg = TRUE;
284 }
285 
286 /*
287  * ":debug".
288  */
289     void
290 ex_debug(eap)
291     exarg_T	*eap;
292 {
293     int		debug_break_level_save = debug_break_level;
294 
295     debug_break_level = 9999;
296     do_cmdline_cmd(eap->arg);
297     debug_break_level = debug_break_level_save;
298 }
299 
300 static char_u	*debug_breakpoint_name = NULL;
301 static linenr_T	debug_breakpoint_lnum;
302 
303 /*
304  * When debugging or a breakpoint is set on a skipped command, no debug prompt
305  * is shown by do_one_cmd().  This situation is indicated by debug_skipped, and
306  * debug_skipped_name is then set to the source name in the breakpoint case.  If
307  * a skipped command decides itself that a debug prompt should be displayed, it
308  * can do so by calling dbg_check_skipped().
309  */
310 static int	debug_skipped;
311 static char_u	*debug_skipped_name;
312 
313 /*
314  * Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is
315  * at or below the break level.  But only when the line is actually
316  * executed.  Return TRUE and set breakpoint_name for skipped commands that
317  * decide to execute something themselves.
318  * Called from do_one_cmd() before executing a command.
319  */
320     void
321 dbg_check_breakpoint(eap)
322     exarg_T	*eap;
323 {
324     char_u	*p;
325 
326     debug_skipped = FALSE;
327     if (debug_breakpoint_name != NULL)
328     {
329 	if (!eap->skip)
330 	{
331 	    /* replace K_SNR with "<SNR>" */
332 	    if (debug_breakpoint_name[0] == K_SPECIAL
333 		    && debug_breakpoint_name[1] == KS_EXTRA
334 		    && debug_breakpoint_name[2] == (int)KE_SNR)
335 		p = (char_u *)"<SNR>";
336 	    else
337 		p = (char_u *)"";
338 	    smsg((char_u *)_("Breakpoint in \"%s%s\" line %ld"),
339 		    p,
340 		    debug_breakpoint_name + (*p == NUL ? 0 : 3),
341 		    (long)debug_breakpoint_lnum);
342 	    debug_breakpoint_name = NULL;
343 	    do_debug(eap->cmd);
344 	}
345 	else
346 	{
347 	    debug_skipped = TRUE;
348 	    debug_skipped_name = debug_breakpoint_name;
349 	    debug_breakpoint_name = NULL;
350 	}
351     }
352     else if (ex_nesting_level <= debug_break_level)
353     {
354 	if (!eap->skip)
355 	    do_debug(eap->cmd);
356 	else
357 	{
358 	    debug_skipped = TRUE;
359 	    debug_skipped_name = NULL;
360 	}
361     }
362 }
363 
364 /*
365  * Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was
366  * set.  Return TRUE when the debug mode is entered this time.
367  */
368     int
369 dbg_check_skipped(eap)
370     exarg_T	*eap;
371 {
372     int		prev_got_int;
373 
374     if (debug_skipped)
375     {
376 	/*
377 	 * Save the value of got_int and reset it.  We don't want a previous
378 	 * interruption cause flushing the input buffer.
379 	 */
380 	prev_got_int = got_int;
381 	got_int = FALSE;
382 	debug_breakpoint_name = debug_skipped_name;
383 	/* eap->skip is TRUE */
384 	eap->skip = FALSE;
385 	(void)dbg_check_breakpoint(eap);
386 	eap->skip = TRUE;
387 	got_int |= prev_got_int;
388 	return TRUE;
389     }
390     return FALSE;
391 }
392 
393 /*
394  * The list of breakpoints: dbg_breakp.
395  * This is a grow-array of structs.
396  */
397 struct debuggy
398 {
399     int		dbg_nr;		/* breakpoint number */
400     int		dbg_type;	/* DBG_FUNC or DBG_FILE */
401     char_u	*dbg_name;	/* function or file name */
402     regprog_T	*dbg_prog;	/* regexp program */
403     linenr_T	dbg_lnum;	/* line number in function or file */
404     int		dbg_forceit;	/* ! used */
405 };
406 
407 static garray_T dbg_breakp = {0, 0, sizeof(struct debuggy), 4, NULL};
408 #define BREAKP(idx)		(((struct debuggy *)dbg_breakp.ga_data)[idx])
409 #define DEBUGGY(gap, idx)	(((struct debuggy *)gap->ga_data)[idx])
410 static int last_breakp = 0;	/* nr of last defined breakpoint */
411 
412 #ifdef FEAT_PROFILE
413 /* Profiling uses file and func names similar to breakpoints. */
414 static garray_T prof_ga = {0, 0, sizeof(struct debuggy), 4, NULL};
415 #endif
416 #define DBG_FUNC	1
417 #define DBG_FILE	2
418 
419 static int dbg_parsearg __ARGS((char_u *arg, garray_T *gap));
420 static linenr_T debuggy_find __ARGS((int file,char_u *fname, linenr_T after, garray_T *gap, int *fp));
421 
422 /*
423  * Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
424  * in the entry just after the last one in dbg_breakp.  Note that "dbg_name"
425  * is allocated.
426  * Returns FAIL for failure.
427  */
428     static int
429 dbg_parsearg(arg, gap)
430     char_u	*arg;
431     garray_T	*gap;	    /* either &dbg_breakp or &prof_ga */
432 {
433     char_u	*p = arg;
434     char_u	*q;
435     struct debuggy *bp;
436     int		here = FALSE;
437 
438     if (ga_grow(gap, 1) == FAIL)
439 	return FAIL;
440     bp = &DEBUGGY(gap, gap->ga_len);
441 
442     /* Find "func" or "file". */
443     if (STRNCMP(p, "func", 4) == 0)
444 	bp->dbg_type = DBG_FUNC;
445     else if (STRNCMP(p, "file", 4) == 0)
446 	bp->dbg_type = DBG_FILE;
447     else if (
448 #ifdef FEAT_PROFILE
449 	    gap != &prof_ga &&
450 #endif
451 	    STRNCMP(p, "here", 4) == 0)
452     {
453 	if (curbuf->b_ffname == NULL)
454 	{
455 	    EMSG(_(e_noname));
456 	    return FAIL;
457 	}
458 	bp->dbg_type = DBG_FILE;
459 	here = TRUE;
460     }
461     else
462     {
463 	EMSG2(_(e_invarg2), p);
464 	return FAIL;
465     }
466     p = skipwhite(p + 4);
467 
468     /* Find optional line number. */
469     if (here)
470 	bp->dbg_lnum = curwin->w_cursor.lnum;
471     else if (
472 #ifdef FEAT_PROFILE
473 	    gap != &prof_ga &&
474 #endif
475 	    VIM_ISDIGIT(*p))
476     {
477 	bp->dbg_lnum = getdigits(&p);
478 	p = skipwhite(p);
479     }
480     else
481 	bp->dbg_lnum = 0;
482 
483     /* Find the function or file name.  Don't accept a function name with (). */
484     if ((!here && *p == NUL)
485 	    || (here && *p != NUL)
486 	    || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL))
487     {
488 	EMSG2(_(e_invarg2), arg);
489 	return FAIL;
490     }
491 
492     if (bp->dbg_type == DBG_FUNC)
493 	bp->dbg_name = vim_strsave(p);
494     else if (here)
495 	bp->dbg_name = vim_strsave(curbuf->b_ffname);
496     else
497     {
498 	/* Expand the file name in the same way as do_source().  This means
499 	 * doing it twice, so that $DIR/file gets expanded when $DIR is
500 	 * "~/dir". */
501 #ifdef RISCOS
502 	q = mch_munge_fname(p);
503 #else
504 	q = expand_env_save(p);
505 #endif
506 	if (q == NULL)
507 	    return FAIL;
508 #ifdef RISCOS
509 	p = mch_munge_fname(q);
510 #else
511 	p = expand_env_save(q);
512 #endif
513 	vim_free(q);
514 	if (p == NULL)
515 	    return FAIL;
516 	if (*p != '*')
517 	{
518 	    bp->dbg_name = fix_fname(p);
519 	    vim_free(p);
520 	}
521 	else
522 	    bp->dbg_name = p;
523     }
524 
525     if (bp->dbg_name == NULL)
526 	return FAIL;
527     return OK;
528 }
529 
530 /*
531  * ":breakadd".
532  */
533     void
534 ex_breakadd(eap)
535     exarg_T	*eap;
536 {
537     struct debuggy *bp;
538     char_u	*pat;
539     garray_T	*gap;
540 
541     gap = &dbg_breakp;
542 #ifdef FEAT_PROFILE
543     if (eap->cmdidx == CMD_profile)
544 	gap = &prof_ga;
545 #endif
546 
547     if (dbg_parsearg(eap->arg, gap) == OK)
548     {
549 	bp = &DEBUGGY(gap, gap->ga_len);
550 	bp->dbg_forceit = eap->forceit;
551 
552 	pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, FALSE);
553 	if (pat != NULL)
554 	{
555 	    bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
556 	    vim_free(pat);
557 	}
558 	if (pat == NULL || bp->dbg_prog == NULL)
559 	    vim_free(bp->dbg_name);
560 	else
561 	{
562 	    if (bp->dbg_lnum == 0)	/* default line number is 1 */
563 		bp->dbg_lnum = 1;
564 #ifdef FEAT_PROFILE
565 	    if (eap->cmdidx != CMD_profile)
566 #endif
567 	    {
568 		DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
569 		++debug_tick;
570 	    }
571 	    ++gap->ga_len;
572 	}
573     }
574 }
575 
576 /*
577  * ":debuggreedy".
578  */
579     void
580 ex_debuggreedy(eap)
581     exarg_T	*eap;
582 {
583     if (eap->addr_count == 0 || eap->line2 != 0)
584 	debug_greedy = TRUE;
585     else
586 	debug_greedy = FALSE;
587 }
588 
589 /*
590  * ":breakdel" and ":profdel".
591  */
592     void
593 ex_breakdel(eap)
594     exarg_T	*eap;
595 {
596     struct debuggy *bp, *bpi;
597     int		nr;
598     int		todel = -1;
599     int		del_all = FALSE;
600     int		i;
601     linenr_T	best_lnum = 0;
602     garray_T	*gap;
603 
604     gap = &dbg_breakp;
605 #ifdef FEAT_PROFILE
606     if (eap->cmdidx == CMD_profdel)
607 	gap = &prof_ga;
608 #endif
609 
610     if (vim_isdigit(*eap->arg))
611     {
612 	/* ":breakdel {nr}" */
613 	nr = atol((char *)eap->arg);
614 	for (i = 0; i < gap->ga_len; ++i)
615 	    if (DEBUGGY(gap, i).dbg_nr == nr)
616 	    {
617 		todel = i;
618 		break;
619 	    }
620     }
621     else if (*eap->arg == '*')
622     {
623 	todel = 0;
624 	del_all = TRUE;
625     }
626     else
627     {
628 	/* ":breakdel {func|file} [lnum] {name}" */
629 	if (dbg_parsearg(eap->arg, gap) == FAIL)
630 	    return;
631 	bp = &DEBUGGY(gap, gap->ga_len);
632 	for (i = 0; i < gap->ga_len; ++i)
633 	{
634 	    bpi = &DEBUGGY(gap, i);
635 	    if (bp->dbg_type == bpi->dbg_type
636 		    && STRCMP(bp->dbg_name, bpi->dbg_name) == 0
637 		    && (bp->dbg_lnum == bpi->dbg_lnum
638 			|| (bp->dbg_lnum == 0
639 			    && (best_lnum == 0
640 				|| bpi->dbg_lnum < best_lnum))))
641 	    {
642 		todel = i;
643 		best_lnum = bpi->dbg_lnum;
644 	    }
645 	}
646 	vim_free(bp->dbg_name);
647     }
648 
649     if (todel < 0)
650 	EMSG2(_("E161: Breakpoint not found: %s"), eap->arg);
651     else
652     {
653 	while (gap->ga_len > 0)
654 	{
655 	    vim_free(DEBUGGY(gap, todel).dbg_name);
656 	    vim_free(DEBUGGY(gap, todel).dbg_prog);
657 	    --gap->ga_len;
658 	    if (todel < gap->ga_len)
659 		mch_memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1),
660 			      (gap->ga_len - todel) * sizeof(struct debuggy));
661 #ifdef FEAT_PROFILE
662 	    if (eap->cmdidx == CMD_breakdel)
663 #endif
664 		++debug_tick;
665 	    if (!del_all)
666 		break;
667 	}
668 
669 	/* If all breakpoints were removed clear the array. */
670 	if (gap->ga_len == 0)
671 	    ga_clear(gap);
672     }
673 }
674 
675 /*
676  * ":breaklist".
677  */
678 /*ARGSUSED*/
679     void
680 ex_breaklist(eap)
681     exarg_T	*eap;
682 {
683     struct debuggy *bp;
684     int		i;
685 
686     if (dbg_breakp.ga_len == 0)
687 	MSG(_("No breakpoints defined"));
688     else
689 	for (i = 0; i < dbg_breakp.ga_len; ++i)
690 	{
691 	    bp = &BREAKP(i);
692 	    smsg((char_u *)_("%3d  %s %s  line %ld"),
693 		    bp->dbg_nr,
694 		    bp->dbg_type == DBG_FUNC ? "func" : "file",
695 		    bp->dbg_name,
696 		    (long)bp->dbg_lnum);
697 	}
698 }
699 
700 /*
701  * Find a breakpoint for a function or sourced file.
702  * Returns line number at which to break; zero when no matching breakpoint.
703  */
704     linenr_T
705 dbg_find_breakpoint(file, fname, after)
706     int		file;	    /* TRUE for a file, FALSE for a function */
707     char_u	*fname;	    /* file or function name */
708     linenr_T	after;	    /* after this line number */
709 {
710     return debuggy_find(file, fname, after, &dbg_breakp, NULL);
711 }
712 
713 #if defined(FEAT_PROFILE) || defined(PROTO)
714 /*
715  * Return TRUE if profiling is on for a function or sourced file.
716  */
717     int
718 has_profiling(file, fname, fp)
719     int		file;	    /* TRUE for a file, FALSE for a function */
720     char_u	*fname;	    /* file or function name */
721     int		*fp;	    /* return: forceit */
722 {
723     return (debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
724 							      != (linenr_T)0);
725 }
726 #endif
727 
728 /*
729  * Common code for dbg_find_breakpoint() and has_profiling().
730  */
731     static linenr_T
732 debuggy_find(file, fname, after, gap, fp)
733     int		file;	    /* TRUE for a file, FALSE for a function */
734     char_u	*fname;	    /* file or function name */
735     linenr_T	after;	    /* after this line number */
736     garray_T	*gap;	    /* either &dbg_breakp or &prof_ga */
737     int		*fp;	    /* if not NULL: return forceit */
738 {
739     struct debuggy *bp;
740     int		i;
741     linenr_T	lnum = 0;
742     regmatch_T	regmatch;
743     char_u	*name = fname;
744     int		prev_got_int;
745 
746     /* Return quickly when there are no breakpoints. */
747     if (gap->ga_len == 0)
748 	return (linenr_T)0;
749 
750     /* Replace K_SNR in function name with "<SNR>". */
751     if (!file && fname[0] == K_SPECIAL)
752     {
753 	name = alloc((unsigned)STRLEN(fname) + 3);
754 	if (name == NULL)
755 	    name = fname;
756 	else
757 	{
758 	    STRCPY(name, "<SNR>");
759 	    STRCPY(name + 5, fname + 3);
760 	}
761     }
762 
763     for (i = 0; i < gap->ga_len; ++i)
764     {
765 	/* Skip entries that are not useful or are for a line that is beyond
766 	 * an already found breakpoint. */
767 	bp = &DEBUGGY(gap, i);
768 	if (((bp->dbg_type == DBG_FILE) == file && (
769 #ifdef FEAT_PROFILE
770 		gap == &prof_ga ||
771 #endif
772 		(bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))))
773 	{
774 	    regmatch.regprog = bp->dbg_prog;
775 	    regmatch.rm_ic = FALSE;
776 	    /*
777 	     * Save the value of got_int and reset it.  We don't want a
778 	     * previous interruption cancel matching, only hitting CTRL-C
779 	     * while matching should abort it.
780 	     */
781 	    prev_got_int = got_int;
782 	    got_int = FALSE;
783 	    if (vim_regexec(&regmatch, name, (colnr_T)0))
784 	    {
785 		lnum = bp->dbg_lnum;
786 		if (fp != NULL)
787 		    *fp = bp->dbg_forceit;
788 	    }
789 	    got_int |= prev_got_int;
790 	}
791     }
792     if (name != fname)
793 	vim_free(name);
794 
795     return lnum;
796 }
797 
798 /*
799  * Called when a breakpoint was encountered.
800  */
801     void
802 dbg_breakpoint(name, lnum)
803     char_u	*name;
804     linenr_T	lnum;
805 {
806     /* We need to check if this line is actually executed in do_one_cmd() */
807     debug_breakpoint_name = name;
808     debug_breakpoint_lnum = lnum;
809 }
810 
811 
812 # if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO)
813 /*
814  * Store the current time in "tm".
815  */
816     void
817 profile_start(tm)
818     proftime_T *tm;
819 {
820 # ifdef WIN3264
821     QueryPerformanceCounter(tm);
822 # else
823     gettimeofday(tm, NULL);
824 # endif
825 }
826 
827 /*
828  * Compute the elapsed time from "tm" till now and store in "tm".
829  */
830     void
831 profile_end(tm)
832     proftime_T *tm;
833 {
834     proftime_T now;
835 
836 # ifdef WIN3264
837     QueryPerformanceCounter(&now);
838     tm->QuadPart = now.QuadPart - tm->QuadPart;
839 # else
840     gettimeofday(&now, NULL);
841     tm->tv_usec = now.tv_usec - tm->tv_usec;
842     tm->tv_sec = now.tv_sec - tm->tv_sec;
843     if (tm->tv_usec < 0)
844     {
845 	tm->tv_usec += 1000000;
846 	--tm->tv_sec;
847     }
848 # endif
849 }
850 
851 /*
852  * Subtract the time "tm2" from "tm".
853  */
854     void
855 profile_sub(tm, tm2)
856     proftime_T *tm, *tm2;
857 {
858 # ifdef WIN3264
859     tm->QuadPart -= tm2->QuadPart;
860 # else
861     tm->tv_usec -= tm2->tv_usec;
862     tm->tv_sec -= tm2->tv_sec;
863     if (tm->tv_usec < 0)
864     {
865 	tm->tv_usec += 1000000;
866 	--tm->tv_sec;
867     }
868 # endif
869 }
870 
871 /*
872  * Return a string that represents the time in "tm".
873  * Uses a static buffer!
874  */
875     char *
876 profile_msg(tm)
877     proftime_T *tm;
878 {
879     static char buf[50];
880 
881 # ifdef WIN3264
882     LARGE_INTEGER   fr;
883 
884     QueryPerformanceFrequency(&fr);
885     sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart);
886 # else
887     sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec);
888 #endif
889     return buf;
890 }
891 
892 # endif  /* FEAT_PROFILE || FEAT_RELTIME */
893 
894 # if defined(FEAT_PROFILE) || defined(PROTO)
895 /*
896  * Functions for profiling.
897  */
898 static void script_do_profile __ARGS((scriptitem_T *si));
899 static void script_dump_profile __ARGS((FILE *fd));
900 static proftime_T prof_wait_time;
901 
902 /*
903  * Set the time in "tm" to zero.
904  */
905     void
906 profile_zero(tm)
907     proftime_T *tm;
908 {
909 # ifdef WIN3264
910     tm->QuadPart = 0;
911 # else
912     tm->tv_usec = 0;
913     tm->tv_sec = 0;
914 # endif
915 }
916 
917 /*
918  * Add the time "tm2" to "tm".
919  */
920     void
921 profile_add(tm, tm2)
922     proftime_T *tm, *tm2;
923 {
924 # ifdef WIN3264
925     tm->QuadPart += tm2->QuadPart;
926 # else
927     tm->tv_usec += tm2->tv_usec;
928     tm->tv_sec += tm2->tv_sec;
929     if (tm->tv_usec >= 1000000)
930     {
931 	tm->tv_usec -= 1000000;
932 	++tm->tv_sec;
933     }
934 # endif
935 }
936 
937 /*
938  * Add the "self" time from the total time and the children's time.
939  */
940     void
941 profile_self(self, total, children)
942     proftime_T *self, *total, *children;
943 {
944     /* Check that the result won't be negative.  Can happen with recursive
945      * calls. */
946 #ifdef WIN3264
947     if (total->QuadPart <= children->QuadPart)
948 	return;
949 #else
950     if (total->tv_sec < children->tv_sec
951 	    || (total->tv_sec == children->tv_sec
952 		&& total->tv_usec <= children->tv_usec))
953 	return;
954 #endif
955     profile_add(self, total);
956     profile_sub(self, children);
957 }
958 
959 /*
960  * Get the current waittime.
961  */
962     void
963 profile_get_wait(tm)
964     proftime_T *tm;
965 {
966     *tm = prof_wait_time;
967 }
968 
969 /*
970  * Subtract the passed waittime since "tm" from "tma".
971  */
972     void
973 profile_sub_wait(tm, tma)
974     proftime_T *tm, *tma;
975 {
976     proftime_T tm3 = prof_wait_time;
977 
978     profile_sub(&tm3, tm);
979     profile_sub(tma, &tm3);
980 }
981 
982 /*
983  * Return TRUE if "tm1" and "tm2" are equal.
984  */
985     int
986 profile_equal(tm1, tm2)
987     proftime_T *tm1, *tm2;
988 {
989 # ifdef WIN3264
990     return (tm1->QuadPart == tm2->QuadPart);
991 # else
992     return (tm1->tv_usec == tm2->tv_usec && tm1->tv_sec == tm2->tv_sec);
993 # endif
994 }
995 
996 /*
997  * Return <0, 0 or >0 if "tm1" < "tm2", "tm1" == "tm2" or "tm1" > "tm2"
998  */
999     int
1000 profile_cmp(tm1, tm2)
1001     proftime_T *tm1, *tm2;
1002 {
1003 # ifdef WIN3264
1004     return (int)(tm2->QuadPart - tm1->QuadPart);
1005 # else
1006     if (tm1->tv_sec == tm2->tv_sec)
1007 	return tm2->tv_usec - tm1->tv_usec;
1008     return tm2->tv_sec - tm1->tv_sec;
1009 # endif
1010 }
1011 
1012 static char_u	*profile_fname = NULL;
1013 static proftime_T pause_time;
1014 
1015 /*
1016  * ":profile cmd args"
1017  */
1018     void
1019 ex_profile(eap)
1020     exarg_T	*eap;
1021 {
1022     char_u	*e;
1023     int		len;
1024 
1025     e = skiptowhite(eap->arg);
1026     len = e - eap->arg;
1027     e = skipwhite(e);
1028 
1029     if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL)
1030     {
1031 	vim_free(profile_fname);
1032 	profile_fname = vim_strsave(e);
1033 	do_profiling = PROF_YES;
1034 	profile_zero(&prof_wait_time);
1035 	set_vim_var_nr(VV_PROFILING, 1L);
1036     }
1037     else if (do_profiling == PROF_NONE)
1038 	EMSG(_("E750: First use :profile start <fname>"));
1039     else if (STRCMP(eap->arg, "pause") == 0)
1040     {
1041 	if (do_profiling == PROF_YES)
1042 	    profile_start(&pause_time);
1043 	do_profiling = PROF_PAUSED;
1044     }
1045     else if (STRCMP(eap->arg, "continue") == 0)
1046     {
1047 	if (do_profiling == PROF_PAUSED)
1048 	{
1049 	    profile_end(&pause_time);
1050 	    profile_add(&prof_wait_time, &pause_time);
1051 	}
1052 	do_profiling = PROF_YES;
1053     }
1054     else
1055     {
1056 	/* The rest is similar to ":breakadd". */
1057 	ex_breakadd(eap);
1058     }
1059 }
1060 
1061 /*
1062  * Dump the profiling info.
1063  */
1064     void
1065 profile_dump()
1066 {
1067     FILE	*fd;
1068 
1069     if (profile_fname != NULL)
1070     {
1071 	fd = mch_fopen((char *)profile_fname, "w");
1072 	if (fd == NULL)
1073 	    EMSG2(_(e_notopen), profile_fname);
1074 	else
1075 	{
1076 	    script_dump_profile(fd);
1077 	    func_dump_profile(fd);
1078 	    fclose(fd);
1079 	}
1080     }
1081 }
1082 
1083 /*
1084  * Start profiling script "fp".
1085  */
1086     static void
1087 script_do_profile(si)
1088     scriptitem_T    *si;
1089 {
1090     si->sn_pr_count = 0;
1091     profile_zero(&si->sn_pr_total);
1092     profile_zero(&si->sn_pr_self);
1093 
1094     ga_init2(&si->sn_prl_ga, sizeof(sn_prl_T), 100);
1095     si->sn_prl_idx = -1;
1096     si->sn_prof_on = TRUE;
1097     si->sn_pr_nest = 0;
1098 }
1099 
1100 /*
1101  * save time when starting to invoke another script or function.
1102  */
1103     void
1104 script_prof_save(tm)
1105     proftime_T	*tm;	    /* place to store wait time */
1106 {
1107     scriptitem_T    *si;
1108 
1109     if (current_SID > 0 && current_SID <= script_items.ga_len)
1110     {
1111 	si = &SCRIPT_ITEM(current_SID);
1112 	if (si->sn_prof_on && si->sn_pr_nest++ == 0)
1113 	    profile_start(&si->sn_pr_child);
1114     }
1115     profile_get_wait(tm);
1116 }
1117 
1118 /*
1119  * Count time spent in children after invoking another script or function.
1120  */
1121     void
1122 script_prof_restore(tm)
1123     proftime_T	*tm;
1124 {
1125     scriptitem_T    *si;
1126 
1127     if (current_SID > 0 && current_SID <= script_items.ga_len)
1128     {
1129 	si = &SCRIPT_ITEM(current_SID);
1130 	if (si->sn_prof_on && --si->sn_pr_nest == 0)
1131 	{
1132 	    profile_end(&si->sn_pr_child);
1133 	    profile_sub_wait(tm, &si->sn_pr_child); /* don't count wait time */
1134 	    profile_add(&si->sn_pr_children, &si->sn_pr_child);
1135 	    profile_add(&si->sn_prl_children, &si->sn_pr_child);
1136 	}
1137     }
1138 }
1139 
1140 static proftime_T inchar_time;
1141 
1142 /*
1143  * Called when starting to wait for the user to type a character.
1144  */
1145     void
1146 prof_inchar_enter()
1147 {
1148     profile_start(&inchar_time);
1149 }
1150 
1151 /*
1152  * Called when finished waiting for the user to type a character.
1153  */
1154     void
1155 prof_inchar_exit()
1156 {
1157     profile_end(&inchar_time);
1158     profile_add(&prof_wait_time, &inchar_time);
1159 }
1160 
1161 /*
1162  * Dump the profiling results for all scripts in file "fd".
1163  */
1164     static void
1165 script_dump_profile(fd)
1166     FILE    *fd;
1167 {
1168     int		    id;
1169     scriptitem_T    *si;
1170     int		    i;
1171     FILE	    *sfd;
1172     sn_prl_T	    *pp;
1173 
1174     for (id = 1; id <= script_items.ga_len; ++id)
1175     {
1176 	si = &SCRIPT_ITEM(id);
1177 	if (si->sn_prof_on)
1178 	{
1179 	    fprintf(fd, "SCRIPT  %s\n", si->sn_name);
1180 	    if (si->sn_pr_count == 1)
1181 		fprintf(fd, "Sourced 1 time\n");
1182 	    else
1183 		fprintf(fd, "Sourced %d times\n", si->sn_pr_count);
1184 	    fprintf(fd, "Total time: %s\n", profile_msg(&si->sn_pr_total));
1185 	    fprintf(fd, " Self time: %s\n", profile_msg(&si->sn_pr_self));
1186 	    fprintf(fd, "\n");
1187 	    fprintf(fd, "count  total (s)   self (s)\n");
1188 
1189 	    sfd = mch_fopen((char *)si->sn_name, "r");
1190 	    if (sfd == NULL)
1191 		fprintf(fd, "Cannot open file!\n");
1192 	    else
1193 	    {
1194 		for (i = 0; i < si->sn_prl_ga.ga_len; ++i)
1195 		{
1196 		    if (vim_fgets(IObuff, IOSIZE, sfd))
1197 			break;
1198 		    pp = &PRL_ITEM(si, i);
1199 		    if (pp->snp_count > 0)
1200 		    {
1201 			fprintf(fd, "%5d ", pp->snp_count);
1202 			if (profile_equal(&pp->sn_prl_total, &pp->sn_prl_self))
1203 			    fprintf(fd, "           ");
1204 			else
1205 			    fprintf(fd, "%s ", profile_msg(&pp->sn_prl_total));
1206 			fprintf(fd, "%s ", profile_msg(&pp->sn_prl_self));
1207 		    }
1208 		    else
1209 			fprintf(fd, "                            ");
1210 		    fprintf(fd, "%s", IObuff);
1211 		}
1212 		fclose(sfd);
1213 	    }
1214 	    fprintf(fd, "\n");
1215 	}
1216     }
1217 }
1218 
1219 /*
1220  * Return TRUE when a function defined in the current script should be
1221  * profiled.
1222  */
1223     int
1224 prof_def_func()
1225 {
1226     if (current_SID > 0)
1227 	return SCRIPT_ITEM(current_SID).sn_pr_force;
1228     return FALSE;
1229 }
1230 
1231 # endif
1232 #endif
1233 
1234 /*
1235  * If 'autowrite' option set, try to write the file.
1236  * Careful: autocommands may make "buf" invalid!
1237  *
1238  * return FAIL for failure, OK otherwise
1239  */
1240     int
1241 autowrite(buf, forceit)
1242     buf_T	*buf;
1243     int		forceit;
1244 {
1245     if (!(p_aw || p_awa) || !p_write
1246 #ifdef FEAT_QUICKFIX
1247 	/* never autowrite a "nofile" or "nowrite" buffer */
1248 	|| bt_dontwrite(buf)
1249 #endif
1250 	|| (!forceit && buf->b_p_ro) || buf->b_ffname == NULL)
1251 	return FAIL;
1252     return buf_write_all(buf, forceit);
1253 }
1254 
1255 /*
1256  * flush all buffers, except the ones that are readonly
1257  */
1258     void
1259 autowrite_all()
1260 {
1261     buf_T	*buf;
1262 
1263     if (!(p_aw || p_awa) || !p_write)
1264 	return;
1265     for (buf = firstbuf; buf; buf = buf->b_next)
1266 	if (bufIsChanged(buf) && !buf->b_p_ro)
1267 	{
1268 	    (void)buf_write_all(buf, FALSE);
1269 #ifdef FEAT_AUTOCMD
1270 	    /* an autocommand may have deleted the buffer */
1271 	    if (!buf_valid(buf))
1272 		buf = firstbuf;
1273 #endif
1274 	}
1275 }
1276 
1277 /*
1278  * return TRUE if buffer was changed and cannot be abandoned.
1279  */
1280 /*ARGSUSED*/
1281     int
1282 check_changed(buf, checkaw, mult_win, forceit, allbuf)
1283     buf_T	*buf;
1284     int		checkaw;	/* do autowrite if buffer was changed */
1285     int		mult_win;	/* check also when several wins for the buf */
1286     int		forceit;
1287     int		allbuf;		/* may write all buffers */
1288 {
1289     if (       !forceit
1290 	    && bufIsChanged(buf)
1291 	    && (mult_win || buf->b_nwindows <= 1)
1292 	    && (!checkaw || autowrite(buf, forceit) == FAIL))
1293     {
1294 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1295 	if ((p_confirm || cmdmod.confirm) && p_write)
1296 	{
1297 	    buf_T	*buf2;
1298 	    int		count = 0;
1299 
1300 	    if (allbuf)
1301 		for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1302 		    if (bufIsChanged(buf2)
1303 				     && (buf2->b_ffname != NULL
1304 # ifdef FEAT_BROWSE
1305 					 || cmdmod.browse
1306 # endif
1307 					))
1308 			++count;
1309 # ifdef FEAT_AUTOCMD
1310 	    if (!buf_valid(buf))
1311 		/* Autocommand deleted buffer, oops!  It's not changed now. */
1312 		return FALSE;
1313 # endif
1314 	    dialog_changed(buf, count > 1);
1315 # ifdef FEAT_AUTOCMD
1316 	    if (!buf_valid(buf))
1317 		/* Autocommand deleted buffer, oops!  It's not changed now. */
1318 		return FALSE;
1319 # endif
1320 	    return bufIsChanged(buf);
1321 	}
1322 #endif
1323 	EMSG(_(e_nowrtmsg));
1324 	return TRUE;
1325     }
1326     return FALSE;
1327 }
1328 
1329 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO)
1330 
1331 #if defined(FEAT_BROWSE) || defined(PROTO)
1332 /*
1333  * When wanting to write a file without a file name, ask the user for a name.
1334  */
1335     void
1336 browse_save_fname(buf)
1337     buf_T	*buf;
1338 {
1339     if (buf->b_fname == NULL)
1340     {
1341 	char_u *fname;
1342 
1343 	fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"),
1344 						 NULL, NULL, NULL, NULL, buf);
1345 	if (fname != NULL)
1346 	{
1347 	    if (setfname(buf, fname, NULL, TRUE) == OK)
1348 		buf->b_flags |= BF_NOTEDITED;
1349 	    vim_free(fname);
1350 	}
1351     }
1352 }
1353 #endif
1354 
1355 /*
1356  * Ask the user what to do when abondoning a changed buffer.
1357  * Must check 'write' option first!
1358  */
1359     void
1360 dialog_changed(buf, checkall)
1361     buf_T	*buf;
1362     int		checkall;	/* may abandon all changed buffers */
1363 {
1364     char_u	buff[IOSIZE];
1365     int		ret;
1366     buf_T	*buf2;
1367 
1368     dialog_msg(buff, _("Save changes to \"%s\"?"),
1369 			(buf->b_fname != NULL) ?
1370 			buf->b_fname : (char_u *)_("Untitled"));
1371     if (checkall)
1372 	ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
1373     else
1374 	ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
1375 
1376     if (ret == VIM_YES)
1377     {
1378 #ifdef FEAT_BROWSE
1379 	/* May get file name, when there is none */
1380 	browse_save_fname(buf);
1381 #endif
1382 	if (buf->b_fname != NULL)   /* didn't hit Cancel */
1383 	    (void)buf_write_all(buf, FALSE);
1384     }
1385     else if (ret == VIM_NO)
1386     {
1387 	unchanged(buf, TRUE);
1388     }
1389     else if (ret == VIM_ALL)
1390     {
1391 	/*
1392 	 * Write all modified files that can be written.
1393 	 * Skip readonly buffers, these need to be confirmed
1394 	 * individually.
1395 	 */
1396 	for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1397 	{
1398 	    if (bufIsChanged(buf2)
1399 		    && (buf2->b_ffname != NULL
1400 #ifdef FEAT_BROWSE
1401 			|| cmdmod.browse
1402 #endif
1403 			)
1404 		    && !buf2->b_p_ro)
1405 	    {
1406 #ifdef FEAT_BROWSE
1407 		/* May get file name, when there is none */
1408 		browse_save_fname(buf2);
1409 #endif
1410 		if (buf2->b_fname != NULL)   /* didn't hit Cancel */
1411 		    (void)buf_write_all(buf2, FALSE);
1412 #ifdef FEAT_AUTOCMD
1413 		/* an autocommand may have deleted the buffer */
1414 		if (!buf_valid(buf2))
1415 		    buf2 = firstbuf;
1416 #endif
1417 	    }
1418 	}
1419     }
1420     else if (ret == VIM_DISCARDALL)
1421     {
1422 	/*
1423 	 * mark all buffers as unchanged
1424 	 */
1425 	for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1426 	    unchanged(buf2, TRUE);
1427     }
1428 }
1429 #endif
1430 
1431 /*
1432  * Return TRUE if the buffer "buf" can be abandoned, either by making it
1433  * hidden, autowriting it or unloading it.
1434  */
1435     int
1436 can_abandon(buf, forceit)
1437     buf_T	*buf;
1438     int		forceit;
1439 {
1440     return (	   P_HID(buf)
1441 		|| !bufIsChanged(buf)
1442 		|| buf->b_nwindows > 1
1443 		|| autowrite(buf, forceit) == OK
1444 		|| forceit);
1445 }
1446 
1447 /*
1448  * Return TRUE if any buffer was changed and cannot be abandoned.
1449  * That changed buffer becomes the current buffer.
1450  */
1451     int
1452 check_changed_any(hidden)
1453     int		hidden;		/* Only check hidden buffers */
1454 {
1455     buf_T	*buf;
1456     int		save;
1457 #ifdef FEAT_WINDOWS
1458     win_T	*wp;
1459 #endif
1460 
1461     for (;;)
1462     {
1463 	/* check curbuf first: if it was changed we can't abandon it */
1464 	if (!hidden && curbufIsChanged())
1465 	    buf = curbuf;
1466 	else
1467 	{
1468 	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
1469 		if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf))
1470 		    break;
1471 	}
1472 	if (buf == NULL)    /* No buffers changed */
1473 	    return FALSE;
1474 
1475 	if (check_changed(buf, p_awa, TRUE, FALSE, TRUE) && buf_valid(buf))
1476 	    break;	    /* didn't save - still changes */
1477     }
1478 
1479     exiting = FALSE;
1480 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1481     /*
1482      * When ":confirm" used, don't give an error message.
1483      */
1484     if (!(p_confirm || cmdmod.confirm))
1485 #endif
1486     {
1487 	/* There must be a wait_return for this message, do_buffer()
1488 	 * may cause a redraw.  But wait_return() is a no-op when vgetc()
1489 	 * is busy (Quit used from window menu), then make sure we don't
1490 	 * cause a scroll up. */
1491 	if (vgetc_busy)
1492 	{
1493 	    msg_row = cmdline_row;
1494 	    msg_col = 0;
1495 	    msg_didout = FALSE;
1496 	}
1497 	if (EMSG2(_("E162: No write since last change for buffer \"%s\""),
1498 		    buf_spname(buf) != NULL ? (char_u *)buf_spname(buf) :
1499 		    buf->b_fname))
1500 	{
1501 	    save = no_wait_return;
1502 	    no_wait_return = FALSE;
1503 	    wait_return(FALSE);
1504 	    no_wait_return = save;
1505 	}
1506     }
1507 
1508 #ifdef FEAT_WINDOWS
1509     /* Try to find a window that contains the buffer. */
1510     if (buf != curbuf)
1511 	for (wp = firstwin; wp != NULL; wp = wp->w_next)
1512 	    if (wp->w_buffer == buf)
1513 	    {
1514 		win_goto(wp);
1515 # ifdef FEAT_AUTOCMD
1516 		/* Paranoia: did autocms wipe out the buffer with changes? */
1517 		if (!buf_valid(buf))
1518 		    return TRUE;
1519 # endif
1520 		break;
1521 	    }
1522 #endif
1523 
1524     /* Open the changed buffer in the current window. */
1525     if (buf != curbuf)
1526 	set_curbuf(buf, DOBUF_GOTO);
1527 
1528     return TRUE;
1529 }
1530 
1531 /*
1532  * return FAIL if there is no file name, OK if there is one
1533  * give error message for FAIL
1534  */
1535     int
1536 check_fname()
1537 {
1538     if (curbuf->b_ffname == NULL)
1539     {
1540 	EMSG(_(e_noname));
1541 	return FAIL;
1542     }
1543     return OK;
1544 }
1545 
1546 /*
1547  * flush the contents of a buffer, unless it has no file name
1548  *
1549  * return FAIL for failure, OK otherwise
1550  */
1551     int
1552 buf_write_all(buf, forceit)
1553     buf_T	*buf;
1554     int		forceit;
1555 {
1556     int	    retval;
1557 #ifdef FEAT_AUTOCMD
1558     buf_T	*old_curbuf = curbuf;
1559 #endif
1560 
1561     retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
1562 				   (linenr_T)1, buf->b_ml.ml_line_count, NULL,
1563 						  FALSE, forceit, TRUE, FALSE));
1564 #ifdef FEAT_AUTOCMD
1565     if (curbuf != old_curbuf)
1566     {
1567 	msg_source(hl_attr(HLF_W));
1568 	MSG(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
1569     }
1570 #endif
1571     return retval;
1572 }
1573 
1574 /*
1575  * Code to handle the argument list.
1576  */
1577 
1578 static char_u	*do_one_arg __ARGS((char_u *str));
1579 static int	do_arglist __ARGS((char_u *str, int what, int after));
1580 static void	alist_check_arg_idx __ARGS((void));
1581 static int	editing_arg_idx __ARGS((win_T *win));
1582 #ifdef FEAT_LISTCMDS
1583 static int	alist_add_list __ARGS((int count, char_u **files, int after));
1584 #endif
1585 #define AL_SET	1
1586 #define AL_ADD	2
1587 #define AL_DEL	3
1588 
1589 /*
1590  * Isolate one argument, taking backticks.
1591  * Changes the argument in-place, puts a NUL after it.  Backticks remain.
1592  * Return a pointer to the start of the next argument.
1593  */
1594     static char_u *
1595 do_one_arg(str)
1596     char_u *str;
1597 {
1598     char_u	*p;
1599     int		inbacktick;
1600 
1601     inbacktick = FALSE;
1602     for (p = str; *str; ++str)
1603     {
1604 	/* When the backslash is used for escaping the special meaning of a
1605 	 * character we need to keep it until wildcard expansion. */
1606 	if (rem_backslash(str))
1607 	{
1608 	    *p++ = *str++;
1609 	    *p++ = *str;
1610 	}
1611 	else
1612 	{
1613 	    /* An item ends at a space not in backticks */
1614 	    if (!inbacktick && vim_isspace(*str))
1615 		break;
1616 	    if (*str == '`')
1617 		inbacktick ^= TRUE;
1618 	    *p++ = *str;
1619 	}
1620     }
1621     str = skipwhite(str);
1622     *p = NUL;
1623 
1624     return str;
1625 }
1626 
1627 /*
1628  * Separate the arguments in "str" and return a list of pointers in the
1629  * growarray "gap".
1630  */
1631     int
1632 get_arglist(gap, str)
1633     garray_T	*gap;
1634     char_u	*str;
1635 {
1636     ga_init2(gap, (int)sizeof(char_u *), 20);
1637     while (*str != NUL)
1638     {
1639 	if (ga_grow(gap, 1) == FAIL)
1640 	{
1641 	    ga_clear(gap);
1642 	    return FAIL;
1643 	}
1644 	((char_u **)gap->ga_data)[gap->ga_len++] = str;
1645 
1646 	/* Isolate one argument, change it in-place, put a NUL after it. */
1647 	str = do_one_arg(str);
1648     }
1649     return OK;
1650 }
1651 
1652 #if defined(FEAT_QUICKFIX) || defined(FEAT_SYN_HL) || defined(PROTO)
1653 /*
1654  * Parse a list of arguments (file names), expand them and return in
1655  * "fnames[fcountp]".
1656  * Return FAIL or OK.
1657  */
1658     int
1659 get_arglist_exp(str, fcountp, fnamesp)
1660     char_u	*str;
1661     int		*fcountp;
1662     char_u	***fnamesp;
1663 {
1664     garray_T	ga;
1665     int		i;
1666 
1667     if (get_arglist(&ga, str) == FAIL)
1668 	return FAIL;
1669     i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
1670 				       fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
1671     ga_clear(&ga);
1672     return i;
1673 }
1674 #endif
1675 
1676 #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
1677 /*
1678  * Redefine the argument list.
1679  */
1680     void
1681 set_arglist(str)
1682     char_u	*str;
1683 {
1684     do_arglist(str, AL_SET, 0);
1685 }
1686 #endif
1687 
1688 /*
1689  * "what" == AL_SET: Redefine the argument list to 'str'.
1690  * "what" == AL_ADD: add files in 'str' to the argument list after "after".
1691  * "what" == AL_DEL: remove files in 'str' from the argument list.
1692  *
1693  * Return FAIL for failure, OK otherwise.
1694  */
1695 /*ARGSUSED*/
1696     static int
1697 do_arglist(str, what, after)
1698     char_u	*str;
1699     int		what;
1700     int		after;		/* 0 means before first one */
1701 {
1702     garray_T	new_ga;
1703     int		exp_count;
1704     char_u	**exp_files;
1705     int		i;
1706 #ifdef FEAT_LISTCMDS
1707     char_u	*p;
1708     int		match;
1709 #endif
1710 
1711     /*
1712      * Collect all file name arguments in "new_ga".
1713      */
1714     if (get_arglist(&new_ga, str) == FAIL)
1715 	return FAIL;
1716 
1717 #ifdef FEAT_LISTCMDS
1718     if (what == AL_DEL)
1719     {
1720 	regmatch_T	regmatch;
1721 	int		didone;
1722 
1723 	/*
1724 	 * Delete the items: use each item as a regexp and find a match in the
1725 	 * argument list.
1726 	 */
1727 #ifdef CASE_INSENSITIVE_FILENAME
1728 	regmatch.rm_ic = TRUE;		/* Always ignore case */
1729 #else
1730 	regmatch.rm_ic = FALSE;		/* Never ignore case */
1731 #endif
1732 	for (i = 0; i < new_ga.ga_len && !got_int; ++i)
1733 	{
1734 	    p = ((char_u **)new_ga.ga_data)[i];
1735 	    p = file_pat_to_reg_pat(p, NULL, NULL, FALSE);
1736 	    if (p == NULL)
1737 		break;
1738 	    regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
1739 	    if (regmatch.regprog == NULL)
1740 	    {
1741 		vim_free(p);
1742 		break;
1743 	    }
1744 
1745 	    didone = FALSE;
1746 	    for (match = 0; match < ARGCOUNT; ++match)
1747 		if (vim_regexec(&regmatch, alist_name(&ARGLIST[match]),
1748 								  (colnr_T)0))
1749 		{
1750 		    didone = TRUE;
1751 		    vim_free(ARGLIST[match].ae_fname);
1752 		    mch_memmove(ARGLIST + match, ARGLIST + match + 1,
1753 			    (ARGCOUNT - match - 1) * sizeof(aentry_T));
1754 		    --ALIST(curwin)->al_ga.ga_len;
1755 		    if (curwin->w_arg_idx > match)
1756 			--curwin->w_arg_idx;
1757 		    --match;
1758 		}
1759 
1760 	    vim_free(regmatch.regprog);
1761 	    vim_free(p);
1762 	    if (!didone)
1763 		EMSG2(_(e_nomatch2), ((char_u **)new_ga.ga_data)[i]);
1764 	}
1765 	ga_clear(&new_ga);
1766     }
1767     else
1768 #endif
1769     {
1770 	i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
1771 		&exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND);
1772 	ga_clear(&new_ga);
1773 	if (i == FAIL)
1774 	    return FAIL;
1775 	if (exp_count == 0)
1776 	{
1777 	    EMSG(_(e_nomatch));
1778 	    return FAIL;
1779 	}
1780 
1781 #ifdef FEAT_LISTCMDS
1782 	if (what == AL_ADD)
1783 	{
1784 	    (void)alist_add_list(exp_count, exp_files, after);
1785 	    vim_free(exp_files);
1786 	}
1787 	else /* what == AL_SET */
1788 #endif
1789 	    alist_set(ALIST(curwin), exp_count, exp_files, FALSE, NULL, 0);
1790     }
1791 
1792     alist_check_arg_idx();
1793 
1794     return OK;
1795 }
1796 
1797 /*
1798  * Check the validity of the arg_idx for each other window.
1799  */
1800     static void
1801 alist_check_arg_idx()
1802 {
1803 #ifdef FEAT_WINDOWS
1804     win_T	*win;
1805     tabpage_T	*tp;
1806 
1807     FOR_ALL_TAB_WINDOWS(tp, win)
1808 	if (win->w_alist == curwin->w_alist)
1809 	    check_arg_idx(win);
1810 #else
1811     check_arg_idx(curwin);
1812 #endif
1813 }
1814 
1815 /*
1816  * Return TRUE if window "win" is editing then file at the current argument
1817  * index.
1818  */
1819     static int
1820 editing_arg_idx(win)
1821     win_T	*win;
1822 {
1823     return !(win->w_arg_idx >= WARGCOUNT(win)
1824 		|| (win->w_buffer->b_fnum
1825 				      != WARGLIST(win)[win->w_arg_idx].ae_fnum
1826 		    && (win->w_buffer->b_ffname == NULL
1827 			 || !(fullpathcmp(
1828 				 alist_name(&WARGLIST(win)[win->w_arg_idx]),
1829 				win->w_buffer->b_ffname, TRUE) & FPC_SAME))));
1830 }
1831 
1832 /*
1833  * Check if window "win" is editing the w_arg_idx file in its argument list.
1834  */
1835     void
1836 check_arg_idx(win)
1837     win_T	*win;
1838 {
1839     if (WARGCOUNT(win) > 1 && !editing_arg_idx(win))
1840     {
1841 	/* We are not editing the current entry in the argument list.
1842 	 * Set "arg_had_last" if we are editing the last one. */
1843 	win->w_arg_idx_invalid = TRUE;
1844 	if (win->w_arg_idx != WARGCOUNT(win) - 1
1845 		&& arg_had_last == FALSE
1846 #ifdef FEAT_WINDOWS
1847 		&& ALIST(win) == &global_alist
1848 #endif
1849 		&& GARGCOUNT > 0
1850 		&& win->w_arg_idx < GARGCOUNT
1851 		&& (win->w_buffer->b_fnum == GARGLIST[GARGCOUNT - 1].ae_fnum
1852 		    || (win->w_buffer->b_ffname != NULL
1853 			&& (fullpathcmp(alist_name(&GARGLIST[GARGCOUNT - 1]),
1854 				win->w_buffer->b_ffname, TRUE) & FPC_SAME))))
1855 	    arg_had_last = TRUE;
1856     }
1857     else
1858     {
1859 	/* We are editing the current entry in the argument list.
1860 	 * Set "arg_had_last" if it's also the last one */
1861 	win->w_arg_idx_invalid = FALSE;
1862 	if (win->w_arg_idx == WARGCOUNT(win) - 1
1863 #ifdef FEAT_WINDOWS
1864 		&& win->w_alist == &global_alist
1865 #endif
1866 		)
1867 	    arg_had_last = TRUE;
1868     }
1869 }
1870 
1871 /*
1872  * ":args", ":argslocal" and ":argsglobal".
1873  */
1874     void
1875 ex_args(eap)
1876     exarg_T	*eap;
1877 {
1878     int		i;
1879 
1880     if (eap->cmdidx != CMD_args)
1881     {
1882 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
1883 	alist_unlink(ALIST(curwin));
1884 	if (eap->cmdidx == CMD_argglobal)
1885 	    ALIST(curwin) = &global_alist;
1886 	else /* eap->cmdidx == CMD_arglocal */
1887 	    alist_new();
1888 #else
1889 	ex_ni(eap);
1890 	return;
1891 #endif
1892     }
1893 
1894     if (!ends_excmd(*eap->arg))
1895     {
1896 	/*
1897 	 * ":args file ..": define new argument list, handle like ":next"
1898 	 * Also for ":argslocal file .." and ":argsglobal file ..".
1899 	 */
1900 	ex_next(eap);
1901     }
1902     else
1903 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
1904 	if (eap->cmdidx == CMD_args)
1905 #endif
1906     {
1907 	/*
1908 	 * ":args": list arguments.
1909 	 */
1910 	if (ARGCOUNT > 0)
1911 	{
1912 	    /* Overwrite the command, for a short list there is no scrolling
1913 	     * required and no wait_return(). */
1914 	    gotocmdline(TRUE);
1915 	    for (i = 0; i < ARGCOUNT; ++i)
1916 	    {
1917 		if (i == curwin->w_arg_idx)
1918 		    msg_putchar('[');
1919 		msg_outtrans(alist_name(&ARGLIST[i]));
1920 		if (i == curwin->w_arg_idx)
1921 		    msg_putchar(']');
1922 		msg_putchar(' ');
1923 	    }
1924 	}
1925     }
1926 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
1927     else if (eap->cmdidx == CMD_arglocal)
1928     {
1929 	garray_T	*gap = &curwin->w_alist->al_ga;
1930 
1931 	/*
1932 	 * ":argslocal": make a local copy of the global argument list.
1933 	 */
1934 	if (ga_grow(gap, GARGCOUNT) == OK)
1935 	    for (i = 0; i < GARGCOUNT; ++i)
1936 		if (GARGLIST[i].ae_fname != NULL)
1937 		{
1938 		    AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname =
1939 					    vim_strsave(GARGLIST[i].ae_fname);
1940 		    AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
1941 							  GARGLIST[i].ae_fnum;
1942 		    ++gap->ga_len;
1943 		}
1944     }
1945 #endif
1946 }
1947 
1948 /*
1949  * ":previous", ":sprevious", ":Next" and ":sNext".
1950  */
1951     void
1952 ex_previous(eap)
1953     exarg_T	*eap;
1954 {
1955     /* If past the last one already, go to the last one. */
1956     if (curwin->w_arg_idx - (int)eap->line2 >= ARGCOUNT)
1957 	do_argfile(eap, ARGCOUNT - 1);
1958     else
1959 	do_argfile(eap, curwin->w_arg_idx - (int)eap->line2);
1960 }
1961 
1962 /*
1963  * ":rewind", ":first", ":sfirst" and ":srewind".
1964  */
1965     void
1966 ex_rewind(eap)
1967     exarg_T	*eap;
1968 {
1969     do_argfile(eap, 0);
1970 }
1971 
1972 /*
1973  * ":last" and ":slast".
1974  */
1975     void
1976 ex_last(eap)
1977     exarg_T	*eap;
1978 {
1979     do_argfile(eap, ARGCOUNT - 1);
1980 }
1981 
1982 /*
1983  * ":argument" and ":sargument".
1984  */
1985     void
1986 ex_argument(eap)
1987     exarg_T	*eap;
1988 {
1989     int		i;
1990 
1991     if (eap->addr_count > 0)
1992 	i = eap->line2 - 1;
1993     else
1994 	i = curwin->w_arg_idx;
1995     do_argfile(eap, i);
1996 }
1997 
1998 /*
1999  * Edit file "argn" of the argument lists.
2000  */
2001     void
2002 do_argfile(eap, argn)
2003     exarg_T	*eap;
2004     int		argn;
2005 {
2006     int		other;
2007     char_u	*p;
2008     int		old_arg_idx = curwin->w_arg_idx;
2009 
2010     if (argn < 0 || argn >= ARGCOUNT)
2011     {
2012 	if (ARGCOUNT <= 1)
2013 	    EMSG(_("E163: There is only one file to edit"));
2014 	else if (argn < 0)
2015 	    EMSG(_("E164: Cannot go before first file"));
2016 	else
2017 	    EMSG(_("E165: Cannot go beyond last file"));
2018     }
2019     else
2020     {
2021 	setpcmark();
2022 #ifdef FEAT_GUI
2023 	need_mouse_correct = TRUE;
2024 #endif
2025 
2026 #ifdef FEAT_WINDOWS
2027 	/* split window or create new tab page first */
2028 	if (*eap->cmd == 's' || cmdmod.tab != 0)
2029 	{
2030 	    if (win_split(0, 0) == FAIL)
2031 		return;
2032 # ifdef FEAT_SCROLLBIND
2033 	    curwin->w_p_scb = FALSE;
2034 # endif
2035 	}
2036 	else
2037 #endif
2038 	{
2039 	    /*
2040 	     * if 'hidden' set, only check for changed file when re-editing
2041 	     * the same buffer
2042 	     */
2043 	    other = TRUE;
2044 	    if (P_HID(curbuf))
2045 	    {
2046 		p = fix_fname(alist_name(&ARGLIST[argn]));
2047 		other = otherfile(p);
2048 		vim_free(p);
2049 	    }
2050 	    if ((!P_HID(curbuf) || !other)
2051 		  && check_changed(curbuf, TRUE, !other, eap->forceit, FALSE))
2052 		return;
2053 	}
2054 
2055 	curwin->w_arg_idx = argn;
2056 	if (argn == ARGCOUNT - 1
2057 #ifdef FEAT_WINDOWS
2058 		&& curwin->w_alist == &global_alist
2059 #endif
2060 	   )
2061 	    arg_had_last = TRUE;
2062 
2063 	/* Edit the file; always use the last known line number.
2064 	 * When it fails (e.g. Abort for already edited file) restore the
2065 	 * argument index. */
2066 	if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
2067 		      eap, ECMD_LAST,
2068 		      (P_HID(curwin->w_buffer) ? ECMD_HIDE : 0) +
2069 				   (eap->forceit ? ECMD_FORCEIT : 0)) == FAIL)
2070 	    curwin->w_arg_idx = old_arg_idx;
2071 	/* like Vi: set the mark where the cursor is in the file. */
2072 	else if (eap->cmdidx != CMD_argdo)
2073 	    setmark('\'');
2074     }
2075 }
2076 
2077 /*
2078  * ":next", and commands that behave like it.
2079  */
2080     void
2081 ex_next(eap)
2082     exarg_T	*eap;
2083 {
2084     int		i;
2085 
2086     /*
2087      * check for changed buffer now, if this fails the argument list is not
2088      * redefined.
2089      */
2090     if (       P_HID(curbuf)
2091 	    || eap->cmdidx == CMD_snext
2092 	    || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE))
2093     {
2094 	if (*eap->arg != NUL)		    /* redefine file list */
2095 	{
2096 	    if (do_arglist(eap->arg, AL_SET, 0) == FAIL)
2097 		return;
2098 	    i = 0;
2099 	}
2100 	else
2101 	    i = curwin->w_arg_idx + (int)eap->line2;
2102 	do_argfile(eap, i);
2103     }
2104 }
2105 
2106 #ifdef FEAT_LISTCMDS
2107 /*
2108  * ":argedit"
2109  */
2110     void
2111 ex_argedit(eap)
2112     exarg_T	*eap;
2113 {
2114     int		fnum;
2115     int		i;
2116     char_u	*s;
2117 
2118     /* Add the argument to the buffer list and get the buffer number. */
2119     fnum = buflist_add(eap->arg, BLN_LISTED);
2120 
2121     /* Check if this argument is already in the argument list. */
2122     for (i = 0; i < ARGCOUNT; ++i)
2123 	if (ARGLIST[i].ae_fnum == fnum)
2124 	    break;
2125     if (i == ARGCOUNT)
2126     {
2127 	/* Can't find it, add it to the argument list. */
2128 	s = vim_strsave(eap->arg);
2129 	if (s == NULL)
2130 	    return;
2131 	i = alist_add_list(1, &s,
2132 	       eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
2133 	if (i < 0)
2134 	    return;
2135 	curwin->w_arg_idx = i;
2136     }
2137 
2138     alist_check_arg_idx();
2139 
2140     /* Edit the argument. */
2141     do_argfile(eap, i);
2142 }
2143 
2144 /*
2145  * ":argadd"
2146  */
2147     void
2148 ex_argadd(eap)
2149     exarg_T	*eap;
2150 {
2151     do_arglist(eap->arg, AL_ADD,
2152 	       eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
2153 #ifdef FEAT_TITLE
2154     maketitle();
2155 #endif
2156 }
2157 
2158 /*
2159  * ":argdelete"
2160  */
2161     void
2162 ex_argdelete(eap)
2163     exarg_T	*eap;
2164 {
2165     int		i;
2166     int		n;
2167 
2168     if (eap->addr_count > 0)
2169     {
2170 	/* ":1,4argdel": Delete all arguments in the range. */
2171 	if (eap->line2 > ARGCOUNT)
2172 	    eap->line2 = ARGCOUNT;
2173 	n = eap->line2 - eap->line1 + 1;
2174 	if (*eap->arg != NUL || n <= 0)
2175 	    EMSG(_(e_invarg));
2176 	else
2177 	{
2178 	    for (i = eap->line1; i <= eap->line2; ++i)
2179 		vim_free(ARGLIST[i - 1].ae_fname);
2180 	    mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2,
2181 			(size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T)));
2182 	    ALIST(curwin)->al_ga.ga_len -= n;
2183 	    if (curwin->w_arg_idx >= eap->line2)
2184 		curwin->w_arg_idx -= n;
2185 	    else if (curwin->w_arg_idx > eap->line1)
2186 		curwin->w_arg_idx = eap->line1;
2187 	}
2188     }
2189     else if (*eap->arg == NUL)
2190 	EMSG(_(e_argreq));
2191     else
2192 	do_arglist(eap->arg, AL_DEL, 0);
2193 #ifdef FEAT_TITLE
2194     maketitle();
2195 #endif
2196 }
2197 
2198 /*
2199  * ":argdo", ":windo", ":bufdo", ":tabdo"
2200  */
2201     void
2202 ex_listdo(eap)
2203     exarg_T	*eap;
2204 {
2205     int		i;
2206 #ifdef FEAT_WINDOWS
2207     win_T	*wp;
2208     tabpage_T	*tp;
2209 #endif
2210     buf_T	*buf;
2211     int		next_fnum = 0;
2212 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2213     char_u	*save_ei = NULL;
2214 #endif
2215     char_u	*p_shm_save;
2216 
2217 #ifndef FEAT_WINDOWS
2218     if (eap->cmdidx == CMD_windo)
2219     {
2220 	ex_ni(eap);
2221 	return;
2222     }
2223 #endif
2224 
2225 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2226     if (eap->cmdidx != CMD_windo)
2227 	/* Don't do syntax HL autocommands.  Skipping the syntax file is a
2228 	 * great speed improvement. */
2229 	save_ei = au_event_disable(",Syntax");
2230 #endif
2231 
2232     if (eap->cmdidx == CMD_windo
2233 	    || eap->cmdidx == CMD_tabdo
2234 	    || P_HID(curbuf)
2235 	    || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE))
2236     {
2237 	/* start at the first argument/window/buffer */
2238 	i = 0;
2239 #ifdef FEAT_WINDOWS
2240 	wp = firstwin;
2241 	tp = first_tabpage;
2242 #endif
2243 	/* set pcmark now */
2244 	if (eap->cmdidx == CMD_bufdo)
2245 	    goto_buffer(eap, DOBUF_FIRST, FORWARD, 0);
2246 	else
2247 	    setpcmark();
2248 	listcmd_busy = TRUE;	    /* avoids setting pcmark below */
2249 
2250 	while (!got_int)
2251 	{
2252 	    if (eap->cmdidx == CMD_argdo)
2253 	    {
2254 		/* go to argument "i" */
2255 		if (i == ARGCOUNT)
2256 		    break;
2257 		/* Don't call do_argfile() when already there, it will try
2258 		 * reloading the file. */
2259 		if (curwin->w_arg_idx != i || !editing_arg_idx(curwin))
2260 		{
2261 		    /* Clear 'shm' to avoid that the file message overwrites
2262 		     * any output from the command. */
2263 		    p_shm_save = vim_strsave(p_shm);
2264 		    set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
2265 		    do_argfile(eap, i);
2266 		    set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
2267 		    vim_free(p_shm_save);
2268 		}
2269 		if (curwin->w_arg_idx != i)
2270 		    break;
2271 		++i;
2272 	    }
2273 #ifdef FEAT_WINDOWS
2274 	    else if (eap->cmdidx == CMD_windo)
2275 	    {
2276 		/* go to window "wp" */
2277 		if (!win_valid(wp))
2278 		    break;
2279 		win_goto(wp);
2280 		wp = curwin->w_next;
2281 	    }
2282 	    else if (eap->cmdidx == CMD_tabdo)
2283 	    {
2284 		/* go to window "tp" */
2285 		if (!valid_tabpage(tp))
2286 		    break;
2287 		goto_tabpage_tp(tp);
2288 		tp = tp->tp_next;
2289 	    }
2290 #endif
2291 	    else if (eap->cmdidx == CMD_bufdo)
2292 	    {
2293 		/* Remember the number of the next listed buffer, in case
2294 		 * ":bwipe" is used or autocommands do something strange. */
2295 		next_fnum = -1;
2296 		for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
2297 		    if (buf->b_p_bl)
2298 		    {
2299 			next_fnum = buf->b_fnum;
2300 			break;
2301 		    }
2302 	    }
2303 
2304 	    /* execute the command */
2305 	    do_cmdline(eap->arg, eap->getline, eap->cookie,
2306 						DOCMD_VERBOSE + DOCMD_NOWAIT);
2307 
2308 	    if (eap->cmdidx == CMD_bufdo)
2309 	    {
2310 		/* Done? */
2311 		if (next_fnum < 0)
2312 		    break;
2313 		/* Check if the buffer still exists. */
2314 		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
2315 		    if (buf->b_fnum == next_fnum)
2316 			break;
2317 		if (buf == NULL)
2318 		    break;
2319 
2320 		/* Go to the next buffer.  Clear 'shm' to avoid that the file
2321 		 * message overwrites any output from the command. */
2322 		p_shm_save = vim_strsave(p_shm);
2323 		set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
2324 		goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
2325 		set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
2326 		vim_free(p_shm_save);
2327 
2328 		/* If autocommands took us elsewhere, quit here */
2329 		if (curbuf->b_fnum != next_fnum)
2330 		    break;
2331 	    }
2332 
2333 	    if (eap->cmdidx == CMD_windo)
2334 	    {
2335 		validate_cursor();	/* cursor may have moved */
2336 #ifdef FEAT_SCROLLBIND
2337 		/* required when 'scrollbind' has been set */
2338 		if (curwin->w_p_scb)
2339 		    do_check_scrollbind(TRUE);
2340 #endif
2341 	    }
2342 	}
2343 	listcmd_busy = FALSE;
2344     }
2345 
2346 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2347     if (save_ei != NULL)
2348     {
2349 	au_event_restore(save_ei);
2350 	apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
2351 					       curbuf->b_fname, TRUE, curbuf);
2352     }
2353 #endif
2354 }
2355 
2356 /*
2357  * Add files[count] to the arglist of the current window after arg "after".
2358  * The file names in files[count] must have been allocated and are taken over.
2359  * Files[] itself is not taken over.
2360  * Returns index of first added argument.  Returns -1 when failed (out of mem).
2361  */
2362     static int
2363 alist_add_list(count, files, after)
2364     int		count;
2365     char_u	**files;
2366     int		after;	    /* where to add: 0 = before first one */
2367 {
2368     int		i;
2369 
2370     if (ga_grow(&ALIST(curwin)->al_ga, count) == OK)
2371     {
2372 	if (after < 0)
2373 	    after = 0;
2374 	if (after > ARGCOUNT)
2375 	    after = ARGCOUNT;
2376 	if (after < ARGCOUNT)
2377 	    mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
2378 				       (ARGCOUNT - after) * sizeof(aentry_T));
2379 	for (i = 0; i < count; ++i)
2380 	{
2381 	    ARGLIST[after + i].ae_fname = files[i];
2382 	    ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
2383 	}
2384 	ALIST(curwin)->al_ga.ga_len += count;
2385 	if (curwin->w_arg_idx >= after)
2386 	    ++curwin->w_arg_idx;
2387 	return after;
2388     }
2389 
2390     for (i = 0; i < count; ++i)
2391 	vim_free(files[i]);
2392     return -1;
2393 }
2394 
2395 #endif /* FEAT_LISTCMDS */
2396 
2397 #ifdef FEAT_EVAL
2398 /*
2399  * ":compiler[!] {name}"
2400  */
2401     void
2402 ex_compiler(eap)
2403     exarg_T	*eap;
2404 {
2405     char_u	*buf;
2406     char_u	*old_cur_comp = NULL;
2407     char_u	*p;
2408 
2409     if (*eap->arg == NUL)
2410     {
2411 	/* List all compiler scripts. */
2412 	do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')");
2413 					/* ) keep the indenter happy... */
2414     }
2415     else
2416     {
2417 	buf = alloc((unsigned)(STRLEN(eap->arg) + 14));
2418 	if (buf != NULL)
2419 	{
2420 	    if (eap->forceit)
2421 	    {
2422 		/* ":compiler! {name}" sets global options */
2423 		do_cmdline_cmd((char_u *)
2424 				   "command -nargs=* CompilerSet set <args>");
2425 	    }
2426 	    else
2427 	    {
2428 		/* ":compiler! {name}" sets local options.
2429 		 * To remain backwards compatible "current_compiler" is always
2430 		 * used.  A user's compiler plugin may set it, the distributed
2431 		 * plugin will then skip the settings.  Afterwards set
2432 		 * "b:current_compiler" and restore "current_compiler". */
2433 		old_cur_comp = get_var_value((char_u *)"current_compiler");
2434 		if (old_cur_comp != NULL)
2435 		    old_cur_comp = vim_strsave(old_cur_comp);
2436 		do_cmdline_cmd((char_u *)
2437 			      "command -nargs=* CompilerSet setlocal <args>");
2438 	    }
2439 	    do_unlet((char_u *)"current_compiler", TRUE);
2440 	    do_unlet((char_u *)"b:current_compiler", TRUE);
2441 
2442 	    sprintf((char *)buf, "compiler/%s.vim", eap->arg);
2443 	    if (source_runtime(buf, TRUE) == FAIL)
2444 		EMSG2(_("E666: compiler not supported: %s"), eap->arg);
2445 	    vim_free(buf);
2446 
2447 	    do_cmdline_cmd((char_u *)":delcommand CompilerSet");
2448 
2449 	    /* Set "b:current_compiler" from "current_compiler". */
2450 	    p = get_var_value((char_u *)"current_compiler");
2451 	    if (p != NULL)
2452 		set_internal_string_var((char_u *)"b:current_compiler", p);
2453 
2454 	    /* Restore "current_compiler" for ":compiler {name}". */
2455 	    if (!eap->forceit)
2456 	    {
2457 		if (old_cur_comp != NULL)
2458 		{
2459 		    set_internal_string_var((char_u *)"current_compiler",
2460 								old_cur_comp);
2461 		    vim_free(old_cur_comp);
2462 		}
2463 		else
2464 		    do_unlet((char_u *)"current_compiler", TRUE);
2465 	    }
2466 	}
2467     }
2468 }
2469 #endif
2470 
2471 /*
2472  * ":runtime {name}"
2473  */
2474     void
2475 ex_runtime(eap)
2476     exarg_T	*eap;
2477 {
2478     source_runtime(eap->arg, eap->forceit);
2479 }
2480 
2481 static void source_callback __ARGS((char_u *fname, void *cookie));
2482 
2483 /*ARGSUSED*/
2484     static void
2485 source_callback(fname, cookie)
2486     char_u	*fname;
2487     void	*cookie;
2488 {
2489     (void)do_source(fname, FALSE, FALSE);
2490 }
2491 
2492 /*
2493  * Source the file "name" from all directories in 'runtimepath'.
2494  * "name" can contain wildcards.
2495  * When "all" is TRUE, source all files, otherwise only the first one.
2496  * return FAIL when no file could be sourced, OK otherwise.
2497  */
2498     int
2499 source_runtime(name, all)
2500     char_u	*name;
2501     int		all;
2502 {
2503     return do_in_runtimepath(name, all, source_callback, NULL);
2504 }
2505 
2506 /*
2507  * Find "name" in 'runtimepath'.  When found, invoke the callback function for
2508  * it: callback(fname, "cookie")
2509  * When "all" is TRUE repeat for all matches, otherwise only the first one is
2510  * used.
2511  * Returns OK when at least one match found, FAIL otherwise.
2512  */
2513     int
2514 do_in_runtimepath(name, all, callback, cookie)
2515     char_u	*name;
2516     int		all;
2517     void	(*callback)__ARGS((char_u *fname, void *ck));
2518     void	*cookie;
2519 {
2520     char_u	*rtp;
2521     char_u	*np;
2522     char_u	*buf;
2523     char_u	*rtp_copy;
2524     char_u	*tail;
2525     int		num_files;
2526     char_u	**files;
2527     int		i;
2528     int		did_one = FALSE;
2529 #ifdef AMIGA
2530     struct Process	*proc = (struct Process *)FindTask(0L);
2531     APTR		save_winptr = proc->pr_WindowPtr;
2532 
2533     /* Avoid a requester here for a volume that doesn't exist. */
2534     proc->pr_WindowPtr = (APTR)-1L;
2535 #endif
2536 
2537     /* Make a copy of 'runtimepath'.  Invoking the callback may change the
2538      * value. */
2539     rtp_copy = vim_strsave(p_rtp);
2540     buf = alloc(MAXPATHL);
2541     if (buf != NULL && rtp_copy != NULL)
2542     {
2543 	if (p_verbose > 1)
2544 	{
2545 	    verbose_enter();
2546 	    smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
2547 						 (char *)name, (char *)p_rtp);
2548 	    verbose_leave();
2549 	}
2550 
2551 	/* Loop over all entries in 'runtimepath'. */
2552 	rtp = rtp_copy;
2553 	while (*rtp != NUL && (all || !did_one))
2554 	{
2555 	    /* Copy the path from 'runtimepath' to buf[]. */
2556 	    copy_option_part(&rtp, buf, MAXPATHL, ",");
2557 	    if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL)
2558 	    {
2559 		add_pathsep(buf);
2560 		tail = buf + STRLEN(buf);
2561 
2562 		/* Loop over all patterns in "name" */
2563 		np = name;
2564 		while (*np != NUL && (all || !did_one))
2565 		{
2566 		    /* Append the pattern from "name" to buf[]. */
2567 		    copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)),
2568 								       "\t ");
2569 
2570 		    if (p_verbose > 2)
2571 		    {
2572 			verbose_enter();
2573 			smsg((char_u *)_("Searching for \"%s\""), buf);
2574 			verbose_leave();
2575 		    }
2576 
2577 		    /* Expand wildcards, invoke the callback for each match. */
2578 		    if (gen_expand_wildcards(1, &buf, &num_files, &files,
2579 							       EW_FILE) == OK)
2580 		    {
2581 			for (i = 0; i < num_files; ++i)
2582 			{
2583 			    (*callback)(files[i], cookie);
2584 			    did_one = TRUE;
2585 			    if (!all)
2586 				break;
2587 			}
2588 			FreeWild(num_files, files);
2589 		    }
2590 		}
2591 	    }
2592 	}
2593     }
2594     vim_free(buf);
2595     vim_free(rtp_copy);
2596     if (p_verbose > 0 && !did_one)
2597     {
2598 	verbose_enter();
2599 	smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name);
2600 	verbose_leave();
2601     }
2602 
2603 #ifdef AMIGA
2604     proc->pr_WindowPtr = save_winptr;
2605 #endif
2606 
2607     return did_one ? OK : FAIL;
2608 }
2609 
2610 #if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
2611 /*
2612  * ":options"
2613  */
2614 /*ARGSUSED*/
2615     void
2616 ex_options(eap)
2617     exarg_T	*eap;
2618 {
2619     cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
2620 }
2621 #endif
2622 
2623 /*
2624  * ":source {fname}"
2625  */
2626     void
2627 ex_source(eap)
2628     exarg_T	*eap;
2629 {
2630 #ifdef FEAT_BROWSE
2631     if (cmdmod.browse)
2632     {
2633 	char_u *fname = NULL;
2634 
2635 	fname = do_browse(0, (char_u *)_("Source Vim script"), eap->arg,
2636 				      NULL, NULL, BROWSE_FILTER_MACROS, NULL);
2637 	if (fname != NULL)
2638 	{
2639 	    cmd_source(fname, eap);
2640 	    vim_free(fname);
2641 	}
2642     }
2643     else
2644 #endif
2645 	cmd_source(eap->arg, eap);
2646 }
2647 
2648     static void
2649 cmd_source(fname, eap)
2650     char_u	*fname;
2651     exarg_T	*eap;
2652 {
2653     if (*fname == NUL)
2654 	EMSG(_(e_argreq));
2655 
2656     else if (eap != NULL && eap->forceit)
2657 	/* ":source!": read Normal mdoe commands
2658 	 * Need to execute the commands directly.  This is required at least
2659 	 * for:
2660 	 * - ":g" command busy
2661 	 * - after ":argdo", ":windo" or ":bufdo"
2662 	 * - another command follows
2663 	 * - inside a loop
2664 	 */
2665 	openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL
2666 #ifdef FEAT_EVAL
2667 						 || eap->cstack->cs_idx >= 0
2668 #endif
2669 						 );
2670 
2671     /* ":source" read ex commands */
2672     else if (do_source(fname, FALSE, FALSE) == FAIL)
2673 	EMSG2(_(e_notopen), fname);
2674 }
2675 
2676 /*
2677  * ":source" and associated commands.
2678  */
2679 /*
2680  * Structure used to store info for each sourced file.
2681  * It is shared between do_source() and getsourceline().
2682  * This is required, because it needs to be handed to do_cmdline() and
2683  * sourcing can be done recursively.
2684  */
2685 struct source_cookie
2686 {
2687     FILE	*fp;		/* opened file for sourcing */
2688     char_u      *nextline;      /* if not NULL: line that was read ahead */
2689     int		finished;	/* ":finish" used */
2690 #if defined (USE_CRNL) || defined (USE_CR)
2691     int		fileformat;	/* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
2692     int		error;		/* TRUE if LF found after CR-LF */
2693 #endif
2694 #ifdef FEAT_EVAL
2695     linenr_T	breakpoint;	/* next line with breakpoint or zero */
2696     char_u	*fname;		/* name of sourced file */
2697     int		dbg_tick;	/* debug_tick when breakpoint was set */
2698     int		level;		/* top nesting level of sourced file */
2699 #endif
2700 #ifdef FEAT_MBYTE
2701     vimconv_T	conv;		/* type of conversion */
2702 #endif
2703 };
2704 
2705 #ifdef FEAT_EVAL
2706 /*
2707  * Return the address holding the next breakpoint line for a source cookie.
2708  */
2709     linenr_T *
2710 source_breakpoint(cookie)
2711     void *cookie;
2712 {
2713     return &((struct source_cookie *)cookie)->breakpoint;
2714 }
2715 
2716 /*
2717  * Return the address holding the debug tick for a source cookie.
2718  */
2719     int *
2720 source_dbg_tick(cookie)
2721     void *cookie;
2722 {
2723     return &((struct source_cookie *)cookie)->dbg_tick;
2724 }
2725 
2726 /*
2727  * Return the nesting level for a source cookie.
2728  */
2729     int
2730 source_level(cookie)
2731     void *cookie;
2732 {
2733     return ((struct source_cookie *)cookie)->level;
2734 }
2735 #endif
2736 
2737 static char_u *get_one_sourceline __ARGS((struct source_cookie *sp));
2738 
2739 #if defined(WIN32) && defined(FEAT_CSCOPE)
2740 static FILE *fopen_noinh_readbin __ARGS((char *filename));
2741 
2742 /*
2743  * Special function to open a file without handle inheritance.
2744  */
2745     static FILE *
2746 fopen_noinh_readbin(filename)
2747     char    *filename;
2748 {
2749     int	fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0);
2750 
2751     if (fd_tmp == -1)
2752 	return NULL;
2753     return fdopen(fd_tmp, READBIN);
2754 }
2755 #endif
2756 
2757 
2758 /*
2759  * do_source: Read the file "fname" and execute its lines as EX commands.
2760  *
2761  * This function may be called recursively!
2762  *
2763  * return FAIL if file could not be opened, OK otherwise
2764  */
2765     int
2766 do_source(fname, check_other, is_vimrc)
2767     char_u	*fname;
2768     int		check_other;	    /* check for .vimrc and _vimrc */
2769     int		is_vimrc;	    /* call vimrc_found() when file exists */
2770 {
2771     struct source_cookie    cookie;
2772     char_u		    *save_sourcing_name;
2773     linenr_T		    save_sourcing_lnum;
2774     char_u		    *p;
2775     char_u		    *fname_exp;
2776     int			    retval = FAIL;
2777 #ifdef FEAT_EVAL
2778     scid_T		    save_current_SID;
2779     static scid_T	    last_current_SID = 0;
2780     void		    *save_funccalp;
2781     int			    save_debug_break_level = debug_break_level;
2782     scriptitem_T	    *si = NULL;
2783 # ifdef UNIX
2784     struct stat		    st;
2785     int			    stat_ok;
2786 # endif
2787 #endif
2788 #ifdef STARTUPTIME
2789     struct timeval	    tv_rel;
2790     struct timeval	    tv_start;
2791 #endif
2792 #ifdef FEAT_PROFILE
2793     proftime_T		    wait_start;
2794 #endif
2795 
2796 #ifdef RISCOS
2797     p = mch_munge_fname(fname);
2798 #else
2799     p = expand_env_save(fname);
2800 #endif
2801     if (p == NULL)
2802 	return retval;
2803     fname_exp = fix_fname(p);
2804     vim_free(p);
2805     if (fname_exp == NULL)
2806 	return retval;
2807     if (mch_isdir(fname_exp))
2808     {
2809 	smsg((char_u *)_("Cannot source a directory: \"%s\""), fname);
2810 	goto theend;
2811     }
2812 
2813 #ifdef FEAT_AUTOCMD
2814     apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
2815 #endif
2816 
2817 #if defined(WIN32) && defined(FEAT_CSCOPE)
2818     cookie.fp = fopen_noinh_readbin((char *)fname_exp);
2819 #else
2820     cookie.fp = mch_fopen((char *)fname_exp, READBIN);
2821 #endif
2822     if (cookie.fp == NULL && check_other)
2823     {
2824 	/*
2825 	 * Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
2826 	 * and ".exrc" by "_exrc" or vice versa.
2827 	 */
2828 	p = gettail(fname_exp);
2829 	if ((*p == '.' || *p == '_')
2830 		&& (STRICMP(p + 1, "vimrc") == 0
2831 		    || STRICMP(p + 1, "gvimrc") == 0
2832 		    || STRICMP(p + 1, "exrc") == 0))
2833 	{
2834 	    if (*p == '_')
2835 		*p = '.';
2836 	    else
2837 		*p = '_';
2838 #if defined(WIN32) && defined(FEAT_CSCOPE)
2839 	    cookie.fp = fopen_noinh_readbin((char *)fname_exp);
2840 #else
2841 	    cookie.fp = mch_fopen((char *)fname_exp, READBIN);
2842 #endif
2843 	}
2844     }
2845 
2846     if (cookie.fp == NULL)
2847     {
2848 	if (p_verbose > 0)
2849 	{
2850 	    verbose_enter();
2851 	    if (sourcing_name == NULL)
2852 		smsg((char_u *)_("could not source \"%s\""), fname);
2853 	    else
2854 		smsg((char_u *)_("line %ld: could not source \"%s\""),
2855 							sourcing_lnum, fname);
2856 	    verbose_leave();
2857 	}
2858 	goto theend;
2859     }
2860 
2861     /*
2862      * The file exists.
2863      * - In verbose mode, give a message.
2864      * - For a vimrc file, may want to set 'compatible', call vimrc_found().
2865      */
2866     if (p_verbose > 1)
2867     {
2868 	verbose_enter();
2869 	if (sourcing_name == NULL)
2870 	    smsg((char_u *)_("sourcing \"%s\""), fname);
2871 	else
2872 	    smsg((char_u *)_("line %ld: sourcing \"%s\""),
2873 							sourcing_lnum, fname);
2874 	verbose_leave();
2875     }
2876     if (is_vimrc)
2877 	vimrc_found();
2878 
2879 #ifdef USE_CRNL
2880     /* If no automatic file format: Set default to CR-NL. */
2881     if (*p_ffs == NUL)
2882 	cookie.fileformat = EOL_DOS;
2883     else
2884 	cookie.fileformat = EOL_UNKNOWN;
2885     cookie.error = FALSE;
2886 #endif
2887 
2888 #ifdef USE_CR
2889     /* If no automatic file format: Set default to CR. */
2890     if (*p_ffs == NUL)
2891 	cookie.fileformat = EOL_MAC;
2892     else
2893 	cookie.fileformat = EOL_UNKNOWN;
2894     cookie.error = FALSE;
2895 #endif
2896 
2897     cookie.nextline = NULL;
2898     cookie.finished = FALSE;
2899 
2900 #ifdef FEAT_EVAL
2901     /*
2902      * Check if this script has a breakpoint.
2903      */
2904     cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
2905     cookie.fname = fname_exp;
2906     cookie.dbg_tick = debug_tick;
2907 
2908     cookie.level = ex_nesting_level;
2909 #endif
2910 #ifdef FEAT_MBYTE
2911     cookie.conv.vc_type = CONV_NONE;		/* no conversion */
2912 
2913     /* Try reading the first few bytes to check for a UTF-8 BOM. */
2914     {
2915 	char_u	    buf[3];
2916 
2917 	if (fread((char *)buf, sizeof(char_u), (size_t)3, cookie.fp)
2918 								  == (size_t)3
2919 		&& buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
2920 	    /* Found BOM, setup conversion and skip over it. */
2921 	    convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
2922 	else
2923 	    /* No BOM found, rewind. */
2924 	    fseek(cookie.fp, 0L, SEEK_SET);
2925     }
2926 #endif
2927 
2928     /*
2929      * Keep the sourcing name/lnum, for recursive calls.
2930      */
2931     save_sourcing_name = sourcing_name;
2932     sourcing_name = fname_exp;
2933     save_sourcing_lnum = sourcing_lnum;
2934     sourcing_lnum = 0;
2935 
2936 #ifdef STARTUPTIME
2937     time_push(&tv_rel, &tv_start);
2938 #endif
2939 
2940 #ifdef FEAT_EVAL
2941 # ifdef FEAT_PROFILE
2942     if (do_profiling == PROF_YES)
2943 	prof_child_enter(&wait_start);		/* entering a child now */
2944 # endif
2945 
2946     /* Don't use local function variables, if called from a function.
2947      * Also starts profiling timer for nested script. */
2948     save_funccalp = save_funccal();
2949 
2950     /*
2951      * Check if this script was sourced before to finds its SID.
2952      * If it's new, generate a new SID.
2953      */
2954     save_current_SID = current_SID;
2955 # ifdef UNIX
2956     stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
2957 # endif
2958     for (current_SID = script_items.ga_len; current_SID > 0; --current_SID)
2959     {
2960 	si = &SCRIPT_ITEM(current_SID);
2961 	if (si->sn_name != NULL
2962 		&& (
2963 # ifdef UNIX
2964 		    /* Compare dev/ino when possible, it catches symbolic
2965 		     * links.  Also compare file names, the inode may change
2966 		     * when the file was edited. */
2967 		    ((stat_ok && si->sn_dev != -1)
2968 			&& (si->sn_dev == st.st_dev
2969 			    && si->sn_ino == st.st_ino)) ||
2970 # endif
2971 		fnamecmp(si->sn_name, fname_exp) == 0))
2972 	    break;
2973     }
2974     if (current_SID == 0)
2975     {
2976 	current_SID = ++last_current_SID;
2977 	if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len))
2978 								      == FAIL)
2979 	    goto almosttheend;
2980 	while (script_items.ga_len < current_SID)
2981 	{
2982 	    ++script_items.ga_len;
2983 	    SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
2984 # ifdef FEAT_PROFILE
2985 	    SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
2986 # endif
2987 	}
2988 	si = &SCRIPT_ITEM(current_SID);
2989 	si->sn_name = fname_exp;
2990 	fname_exp = NULL;
2991 # ifdef UNIX
2992 	if (stat_ok)
2993 	{
2994 	    si->sn_dev = st.st_dev;
2995 	    si->sn_ino = st.st_ino;
2996 	}
2997 	else
2998 	    si->sn_dev = -1;
2999 # endif
3000 
3001 	/* Allocate the local script variables to use for this script. */
3002 	new_script_vars(current_SID);
3003     }
3004 
3005 # ifdef FEAT_PROFILE
3006     if (do_profiling == PROF_YES)
3007     {
3008 	int	forceit;
3009 
3010 	/* Check if we do profiling for this script. */
3011 	if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit))
3012 	{
3013 	    script_do_profile(si);
3014 	    si->sn_pr_force = forceit;
3015 	}
3016 	if (si->sn_prof_on)
3017 	{
3018 	    ++si->sn_pr_count;
3019 	    profile_start(&si->sn_pr_start);
3020 	    profile_zero(&si->sn_pr_children);
3021 	}
3022     }
3023 # endif
3024 #endif
3025 
3026     /*
3027      * Call do_cmdline, which will call getsourceline() to get the lines.
3028      */
3029     do_cmdline(NULL, getsourceline, (void *)&cookie,
3030 				     DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
3031 
3032     retval = OK;
3033 
3034 #ifdef FEAT_PROFILE
3035     if (do_profiling == PROF_YES)
3036     {
3037 	/* Get "si" again, "script_items" may have been reallocated. */
3038 	si = &SCRIPT_ITEM(current_SID);
3039 	if (si->sn_prof_on)
3040 	{
3041 	    profile_end(&si->sn_pr_start);
3042 	    profile_sub_wait(&wait_start, &si->sn_pr_start);
3043 	    profile_add(&si->sn_pr_total, &si->sn_pr_start);
3044 	    profile_self(&si->sn_pr_self, &si->sn_pr_start,
3045 							 &si->sn_pr_children);
3046 	}
3047     }
3048 #endif
3049 
3050     if (got_int)
3051 	EMSG(_(e_interr));
3052     sourcing_name = save_sourcing_name;
3053     sourcing_lnum = save_sourcing_lnum;
3054     if (p_verbose > 1)
3055     {
3056 	verbose_enter();
3057 	smsg((char_u *)_("finished sourcing %s"), fname);
3058 	if (sourcing_name != NULL)
3059 	    smsg((char_u *)_("continuing in %s"), sourcing_name);
3060 	verbose_leave();
3061     }
3062 #ifdef STARTUPTIME
3063     vim_snprintf(IObuff, IOSIZE, "sourcing %s", fname);
3064     time_msg(IObuff, &tv_start);
3065     time_pop(&tv_rel);
3066 #endif
3067 
3068 #ifdef FEAT_EVAL
3069     /*
3070      * After a "finish" in debug mode, need to break at first command of next
3071      * sourced file.
3072      */
3073     if (save_debug_break_level > ex_nesting_level
3074 	    && debug_break_level == ex_nesting_level)
3075 	++debug_break_level;
3076 #endif
3077 
3078 #ifdef FEAT_EVAL
3079 almosttheend:
3080     current_SID = save_current_SID;
3081     restore_funccal(save_funccalp);
3082 # ifdef FEAT_PROFILE
3083     if (do_profiling == PROF_YES)
3084 	prof_child_exit(&wait_start);		/* leaving a child now */
3085 # endif
3086 #endif
3087     fclose(cookie.fp);
3088     vim_free(cookie.nextline);
3089 #ifdef FEAT_MBYTE
3090     convert_setup(&cookie.conv, NULL, NULL);
3091 #endif
3092 
3093 theend:
3094     vim_free(fname_exp);
3095     return retval;
3096 }
3097 
3098 #if defined(FEAT_EVAL) || defined(PROTO)
3099 
3100 /*
3101  * ":scriptnames"
3102  */
3103 /*ARGSUSED*/
3104     void
3105 ex_scriptnames(eap)
3106     exarg_T	*eap;
3107 {
3108     int i;
3109 
3110     for (i = 1; i <= script_items.ga_len && !got_int; ++i)
3111 	if (SCRIPT_ITEM(i).sn_name != NULL)
3112 	    smsg((char_u *)"%3d: %s", i, SCRIPT_ITEM(i).sn_name);
3113 }
3114 
3115 # if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
3116 /*
3117  * Fix slashes in the list of script names for 'shellslash'.
3118  */
3119     void
3120 scriptnames_slash_adjust()
3121 {
3122     int i;
3123 
3124     for (i = 1; i <= script_items.ga_len; ++i)
3125 	if (SCRIPT_ITEM(i).sn_name != NULL)
3126 	    slash_adjust(SCRIPT_ITEM(i).sn_name);
3127 }
3128 # endif
3129 
3130 /*
3131  * Get a pointer to a script name.  Used for ":verbose set".
3132  */
3133     char_u *
3134 get_scriptname(id)
3135     scid_T	id;
3136 {
3137     if (id == SID_MODELINE)
3138 	return (char_u *)_("modeline");
3139     if (id == SID_CMDARG)
3140 	return (char_u *)_("--cmd argument");
3141     if (id == SID_CARG)
3142 	return (char_u *)_("-c argument");
3143     if (id == SID_ENV)
3144 	return (char_u *)_("environment variable");
3145     if (id == SID_ERROR)
3146 	return (char_u *)_("error handler");
3147     return SCRIPT_ITEM(id).sn_name;
3148 }
3149 
3150 # if defined(EXITFREE) || defined(PROTO)
3151     void
3152 free_scriptnames()
3153 {
3154     int			i;
3155 
3156     for (i = script_items.ga_len; i > 0; --i)
3157 	vim_free(SCRIPT_ITEM(i).sn_name);
3158     ga_clear(&script_items);
3159 }
3160 # endif
3161 
3162 #endif
3163 
3164 #if defined(USE_CR) || defined(PROTO)
3165 
3166 # if defined(__MSL__) && (__MSL__ >= 22)
3167 /*
3168  * Newer version of the Metrowerks library handle DOS and UNIX files
3169  * without help.
3170  * Test with earlier versions, MSL 2.2 is the library supplied with
3171  * Codewarrior Pro 2.
3172  */
3173     char *
3174 fgets_cr(s, n, stream)
3175     char	*s;
3176     int		n;
3177     FILE	*stream;
3178 {
3179     return fgets(s, n, stream);
3180 }
3181 # else
3182 /*
3183  * Version of fgets() which also works for lines ending in a <CR> only
3184  * (Macintosh format).
3185  * For older versions of the Metrowerks library.
3186  * At least CodeWarrior 9 needed this code.
3187  */
3188     char *
3189 fgets_cr(s, n, stream)
3190     char	*s;
3191     int		n;
3192     FILE	*stream;
3193 {
3194     int	c = 0;
3195     int char_read = 0;
3196 
3197     while (!feof(stream) && c != '\r' && c != '\n' && char_read < n - 1)
3198     {
3199 	c = fgetc(stream);
3200 	s[char_read++] = c;
3201 	/* If the file is in DOS format, we need to skip a NL after a CR.  I
3202 	 * thought it was the other way around, but this appears to work... */
3203 	if (c == '\n')
3204 	{
3205 	    c = fgetc(stream);
3206 	    if (c != '\r')
3207 		ungetc(c, stream);
3208 	}
3209     }
3210 
3211     s[char_read] = 0;
3212     if (char_read == 0)
3213 	return NULL;
3214 
3215     if (feof(stream) && char_read == 1)
3216 	return NULL;
3217 
3218     return s;
3219 }
3220 # endif
3221 #endif
3222 
3223 /*
3224  * Get one full line from a sourced file.
3225  * Called by do_cmdline() when it's called from do_source().
3226  *
3227  * Return a pointer to the line in allocated memory.
3228  * Return NULL for end-of-file or some error.
3229  */
3230 /* ARGSUSED */
3231     char_u *
3232 getsourceline(c, cookie, indent)
3233     int		c;		/* not used */
3234     void	*cookie;
3235     int		indent;		/* not used */
3236 {
3237     struct source_cookie *sp = (struct source_cookie *)cookie;
3238     char_u		*line;
3239     char_u		*p, *s;
3240 
3241 #ifdef FEAT_EVAL
3242     /* If breakpoints have been added/deleted need to check for it. */
3243     if (sp->dbg_tick < debug_tick)
3244     {
3245 	sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
3246 	sp->dbg_tick = debug_tick;
3247     }
3248 # ifdef FEAT_PROFILE
3249     if (do_profiling == PROF_YES)
3250 	script_line_end();
3251 # endif
3252 #endif
3253     /*
3254      * Get current line.  If there is a read-ahead line, use it, otherwise get
3255      * one now.
3256      */
3257     if (sp->finished)
3258 	line = NULL;
3259     else if (sp->nextline == NULL)
3260 	line = get_one_sourceline(sp);
3261     else
3262     {
3263 	line = sp->nextline;
3264 	sp->nextline = NULL;
3265 	++sourcing_lnum;
3266     }
3267 #ifdef FEAT_PROFILE
3268     if (line != NULL && do_profiling == PROF_YES)
3269 	script_line_start();
3270 #endif
3271 
3272     /* Only concatenate lines starting with a \ when 'cpoptions' doesn't
3273      * contain the 'C' flag. */
3274     if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL))
3275     {
3276 	/* compensate for the one line read-ahead */
3277 	--sourcing_lnum;
3278 	for (;;)
3279 	{
3280 	    sp->nextline = get_one_sourceline(sp);
3281 	    if (sp->nextline == NULL)
3282 		break;
3283 	    p = skipwhite(sp->nextline);
3284 	    if (*p != '\\')
3285 		break;
3286 	    s = alloc((int)(STRLEN(line) + STRLEN(p)));
3287 	    if (s == NULL)	/* out of memory */
3288 		break;
3289 	    STRCPY(s, line);
3290 	    STRCAT(s, p + 1);
3291 	    vim_free(line);
3292 	    line = s;
3293 	    vim_free(sp->nextline);
3294 	}
3295     }
3296 
3297 #ifdef FEAT_MBYTE
3298     if (line != NULL && sp->conv.vc_type != CONV_NONE)
3299     {
3300 	/* Convert the encoding of the script line. */
3301 	s = string_convert(&sp->conv, line, NULL);
3302 	if (s != NULL)
3303 	{
3304 	    vim_free(line);
3305 	    line = s;
3306 	}
3307     }
3308 #endif
3309 
3310 #ifdef FEAT_EVAL
3311     /* Did we encounter a breakpoint? */
3312     if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
3313     {
3314 	dbg_breakpoint(sp->fname, sourcing_lnum);
3315 	/* Find next breakpoint. */
3316 	sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
3317 	sp->dbg_tick = debug_tick;
3318     }
3319 #endif
3320 
3321     return line;
3322 }
3323 
3324     static char_u *
3325 get_one_sourceline(sp)
3326     struct source_cookie    *sp;
3327 {
3328     garray_T		ga;
3329     int			len;
3330     int			c;
3331     char_u		*buf;
3332 #ifdef USE_CRNL
3333     int			has_cr;		/* CR-LF found */
3334 #endif
3335 #ifdef USE_CR
3336     char_u		*scan;
3337 #endif
3338     int			have_read = FALSE;
3339 
3340     /* use a growarray to store the sourced line */
3341     ga_init2(&ga, 1, 250);
3342 
3343     /*
3344      * Loop until there is a finished line (or end-of-file).
3345      */
3346     sourcing_lnum++;
3347     for (;;)
3348     {
3349 	/* make room to read at least 120 (more) characters */
3350 	if (ga_grow(&ga, 120) == FAIL)
3351 	    break;
3352 	buf = (char_u *)ga.ga_data;
3353 
3354 #ifdef USE_CR
3355 	if (sp->fileformat == EOL_MAC)
3356 	{
3357 	    if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
3358 							      sp->fp) == NULL)
3359 		break;
3360 	}
3361 	else
3362 #endif
3363 	    if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
3364 							      sp->fp) == NULL)
3365 		break;
3366 	len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
3367 #ifdef USE_CRNL
3368 	/* Ignore a trailing CTRL-Z, when in Dos mode.	Only recognize the
3369 	 * CTRL-Z by its own, or after a NL. */
3370 	if (	   (len == 1 || (len >= 2 && buf[len - 2] == '\n'))
3371 		&& sp->fileformat == EOL_DOS
3372 		&& buf[len - 1] == Ctrl_Z)
3373 	{
3374 	    buf[len - 1] = NUL;
3375 	    break;
3376 	}
3377 #endif
3378 
3379 #ifdef USE_CR
3380 	/* If the read doesn't stop on a new line, and there's
3381 	 * some CR then we assume a Mac format */
3382 	if (sp->fileformat == EOL_UNKNOWN)
3383 	{
3384 	    if (buf[len - 1] != '\n' && vim_strchr(buf, '\r') != NULL)
3385 		sp->fileformat = EOL_MAC;
3386 	    else
3387 		sp->fileformat = EOL_UNIX;
3388 	}
3389 
3390 	if (sp->fileformat == EOL_MAC)
3391 	{
3392 	    scan = vim_strchr(buf, '\r');
3393 
3394 	    if (scan != NULL)
3395 	    {
3396 		*scan = '\n';
3397 		if (*(scan + 1) != 0)
3398 		{
3399 		    *(scan + 1) = 0;
3400 		    fseek(sp->fp, (long)(scan - buf - len + 1), SEEK_CUR);
3401 		}
3402 	    }
3403 	    len = STRLEN(buf);
3404 	}
3405 #endif
3406 
3407 	have_read = TRUE;
3408 	ga.ga_len = len;
3409 
3410 	/* If the line was longer than the buffer, read more. */
3411 	if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
3412 	    continue;
3413 
3414 	if (len >= 1 && buf[len - 1] == '\n')	/* remove trailing NL */
3415 	{
3416 #ifdef USE_CRNL
3417 	    has_cr = (len >= 2 && buf[len - 2] == '\r');
3418 	    if (sp->fileformat == EOL_UNKNOWN)
3419 	    {
3420 		if (has_cr)
3421 		    sp->fileformat = EOL_DOS;
3422 		else
3423 		    sp->fileformat = EOL_UNIX;
3424 	    }
3425 
3426 	    if (sp->fileformat == EOL_DOS)
3427 	    {
3428 		if (has_cr)	    /* replace trailing CR */
3429 		{
3430 		    buf[len - 2] = '\n';
3431 		    --len;
3432 		    --ga.ga_len;
3433 		}
3434 		else	    /* lines like ":map xx yy^M" will have failed */
3435 		{
3436 		    if (!sp->error)
3437 		    {
3438 			msg_source(hl_attr(HLF_W));
3439 			EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
3440 		    }
3441 		    sp->error = TRUE;
3442 		    sp->fileformat = EOL_UNIX;
3443 		}
3444 	    }
3445 #endif
3446 	    /* The '\n' is escaped if there is an odd number of ^V's just
3447 	     * before it, first set "c" just before the 'V's and then check
3448 	     * len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo */
3449 	    for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--)
3450 		;
3451 	    if ((len & 1) != (c & 1))	/* escaped NL, read more */
3452 	    {
3453 		sourcing_lnum++;
3454 		continue;
3455 	    }
3456 
3457 	    buf[len - 1] = NUL;		/* remove the NL */
3458 	}
3459 
3460 	/*
3461 	 * Check for ^C here now and then, so recursive :so can be broken.
3462 	 */
3463 	line_breakcheck();
3464 	break;
3465     }
3466 
3467     if (have_read)
3468 	return (char_u *)ga.ga_data;
3469 
3470     vim_free(ga.ga_data);
3471     return NULL;
3472 }
3473 
3474 #if defined(FEAT_PROFILE) || defined(PROTO)
3475 /*
3476  * Called when starting to read a script line.
3477  * "sourcing_lnum" must be correct!
3478  * When skipping lines it may not actually be executed, but we won't find out
3479  * until later and we need to store the time now.
3480  */
3481     void
3482 script_line_start()
3483 {
3484     scriptitem_T    *si;
3485     sn_prl_T	    *pp;
3486 
3487     if (current_SID <= 0 || current_SID > script_items.ga_len)
3488 	return;
3489     si = &SCRIPT_ITEM(current_SID);
3490     if (si->sn_prof_on && sourcing_lnum >= 1)
3491     {
3492 	/* Grow the array before starting the timer, so that the time spend
3493 	 * here isn't counted. */
3494 	ga_grow(&si->sn_prl_ga, (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
3495 	si->sn_prl_idx = sourcing_lnum - 1;
3496 	while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
3497 		&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
3498 	{
3499 	    /* Zero counters for a line that was not used before. */
3500 	    pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len);
3501 	    pp->snp_count = 0;
3502 	    profile_zero(&pp->sn_prl_total);
3503 	    profile_zero(&pp->sn_prl_self);
3504 	    ++si->sn_prl_ga.ga_len;
3505 	}
3506 	si->sn_prl_execed = FALSE;
3507 	profile_start(&si->sn_prl_start);
3508 	profile_zero(&si->sn_prl_children);
3509 	profile_get_wait(&si->sn_prl_wait);
3510     }
3511 }
3512 
3513 /*
3514  * Called when actually executing a function line.
3515  */
3516     void
3517 script_line_exec()
3518 {
3519     scriptitem_T    *si;
3520 
3521     if (current_SID <= 0 || current_SID > script_items.ga_len)
3522 	return;
3523     si = &SCRIPT_ITEM(current_SID);
3524     if (si->sn_prof_on && si->sn_prl_idx >= 0)
3525 	si->sn_prl_execed = TRUE;
3526 }
3527 
3528 /*
3529  * Called when done with a function line.
3530  */
3531     void
3532 script_line_end()
3533 {
3534     scriptitem_T    *si;
3535     sn_prl_T	    *pp;
3536 
3537     if (current_SID <= 0 || current_SID > script_items.ga_len)
3538 	return;
3539     si = &SCRIPT_ITEM(current_SID);
3540     if (si->sn_prof_on && si->sn_prl_idx >= 0
3541 				     && si->sn_prl_idx < si->sn_prl_ga.ga_len)
3542     {
3543 	if (si->sn_prl_execed)
3544 	{
3545 	    pp = &PRL_ITEM(si, si->sn_prl_idx);
3546 	    ++pp->snp_count;
3547 	    profile_end(&si->sn_prl_start);
3548 	    profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start);
3549 	    profile_add(&pp->sn_prl_total, &si->sn_prl_start);
3550 	    profile_self(&pp->sn_prl_self, &si->sn_prl_start,
3551 							&si->sn_prl_children);
3552 	}
3553 	si->sn_prl_idx = -1;
3554     }
3555 }
3556 #endif
3557 
3558 /*
3559  * ":scriptencoding": Set encoding conversion for a sourced script.
3560  * Without the multi-byte feature it's simply ignored.
3561  */
3562 /*ARGSUSED*/
3563     void
3564 ex_scriptencoding(eap)
3565     exarg_T	*eap;
3566 {
3567 #ifdef FEAT_MBYTE
3568     struct source_cookie	*sp;
3569     char_u			*name;
3570 
3571     if (!getline_equal(eap->getline, eap->cookie, getsourceline))
3572     {
3573 	EMSG(_("E167: :scriptencoding used outside of a sourced file"));
3574 	return;
3575     }
3576 
3577     if (*eap->arg != NUL)
3578     {
3579 	name = enc_canonize(eap->arg);
3580 	if (name == NULL)	/* out of memory */
3581 	    return;
3582     }
3583     else
3584 	name = eap->arg;
3585 
3586     /* Setup for conversion from the specified encoding to 'encoding'. */
3587     sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie);
3588     convert_setup(&sp->conv, name, p_enc);
3589 
3590     if (name != eap->arg)
3591 	vim_free(name);
3592 #endif
3593 }
3594 
3595 #if defined(FEAT_EVAL) || defined(PROTO)
3596 /*
3597  * ":finish": Mark a sourced file as finished.
3598  */
3599     void
3600 ex_finish(eap)
3601     exarg_T	*eap;
3602 {
3603     if (getline_equal(eap->getline, eap->cookie, getsourceline))
3604 	do_finish(eap, FALSE);
3605     else
3606 	EMSG(_("E168: :finish used outside of a sourced file"));
3607 }
3608 
3609 /*
3610  * Mark a sourced file as finished.  Possibly makes the ":finish" pending.
3611  * Also called for a pending finish at the ":endtry" or after returning from
3612  * an extra do_cmdline().  "reanimate" is used in the latter case.
3613  */
3614     void
3615 do_finish(eap, reanimate)
3616     exarg_T	*eap;
3617     int		reanimate;
3618 {
3619     int		idx;
3620 
3621     if (reanimate)
3622 	((struct source_cookie *)getline_cookie(eap->getline,
3623 					      eap->cookie))->finished = FALSE;
3624 
3625     /*
3626      * Cleanup (and inactivate) conditionals, but stop when a try conditional
3627      * not in its finally clause (which then is to be executed next) is found.
3628      * In this case, make the ":finish" pending for execution at the ":endtry".
3629      * Otherwise, finish normally.
3630      */
3631     idx = cleanup_conditionals(eap->cstack, 0, TRUE);
3632     if (idx >= 0)
3633     {
3634 	eap->cstack->cs_pending[idx] = CSTP_FINISH;
3635 	report_make_pending(CSTP_FINISH, NULL);
3636     }
3637     else
3638 	((struct source_cookie *)getline_cookie(eap->getline,
3639 					       eap->cookie))->finished = TRUE;
3640 }
3641 
3642 
3643 /*
3644  * Return TRUE when a sourced file had the ":finish" command: Don't give error
3645  * message for missing ":endif".
3646  * Return FALSE when not sourcing a file.
3647  */
3648     int
3649 source_finished(getline, cookie)
3650     char_u	*(*getline) __ARGS((int, void *, int));
3651     void	*cookie;
3652 {
3653     return (getline_equal(getline, cookie, getsourceline)
3654 	    && ((struct source_cookie *)getline_cookie(
3655 						 getline, cookie))->finished);
3656 }
3657 #endif
3658 
3659 #if defined(FEAT_LISTCMDS) || defined(PROTO)
3660 /*
3661  * ":checktime [buffer]"
3662  */
3663     void
3664 ex_checktime(eap)
3665     exarg_T	*eap;
3666 {
3667     buf_T	*buf;
3668     int		save_no_check_timestamps = no_check_timestamps;
3669 
3670     no_check_timestamps = 0;
3671     if (eap->addr_count == 0)	/* default is all buffers */
3672 	check_timestamps(FALSE);
3673     else
3674     {
3675 	buf = buflist_findnr((int)eap->line2);
3676 	if (buf != NULL)	/* cannot happen? */
3677 	    (void)buf_check_timestamp(buf, FALSE);
3678     }
3679     no_check_timestamps = save_no_check_timestamps;
3680 }
3681 #endif
3682 
3683 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3684 	&& (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG))
3685 static char *get_locale_val __ARGS((int what));
3686 
3687     static char *
3688 get_locale_val(what)
3689     int		what;
3690 {
3691     char	*loc;
3692 
3693     /* Obtain the locale value from the libraries.  For DJGPP this is
3694      * redefined and it doesn't use the arguments. */
3695     loc = setlocale(what, NULL);
3696 
3697 # if defined(__BORLANDC__)
3698     if (loc != NULL)
3699     {
3700 	char_u	*p;
3701 
3702 	/* Borland returns something like "LC_CTYPE=<name>\n"
3703 	 * Let's try to fix that bug here... */
3704 	p = vim_strchr(loc, '=');
3705 	if (p != NULL)
3706 	{
3707 	    loc = ++p;
3708 	    while (*p != NUL)	/* remove trailing newline */
3709 	    {
3710 		if (*p < ' ')
3711 		{
3712 		    *p = NUL;
3713 		    break;
3714 		}
3715 		++p;
3716 	    }
3717 	}
3718     }
3719 # endif
3720 
3721     return loc;
3722 }
3723 #endif
3724 
3725 
3726 #ifdef WIN32
3727 /*
3728  * On MS-Windows locale names are strings like "German_Germany.1252", but
3729  * gettext expects "de".  Try to translate one into another here for a few
3730  * supported languages.
3731  */
3732     static char_u *
3733 gettext_lang(char_u *name)
3734 {
3735     int		i;
3736     static char *(mtable[]) = {
3737 			"afrikaans",	"af",
3738 			"czech",	"cs",
3739 			"dutch",	"nl",
3740 			"german",	"de",
3741 			"english_united kingdom", "en_GB",
3742 			"spanish",	"es",
3743 			"french",	"fr",
3744 			"italian",	"it",
3745 			"japanese",	"ja",
3746 			"korean",	"ko",
3747 			"norwegian",	"no",
3748 			"polish",	"pl",
3749 			"russian",	"ru",
3750 			"slovak",	"sk",
3751 			"swedish",	"sv",
3752 			"ukrainian",	"uk",
3753 			"chinese_china", "zh_CN",
3754 			"chinese_taiwan", "zh_TW",
3755 			NULL};
3756 
3757     for (i = 0; mtable[i] != NULL; i += 2)
3758 	if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0)
3759 	    return mtable[i + 1];
3760     return name;
3761 }
3762 #endif
3763 
3764 #if defined(FEAT_MULTI_LANG) || defined(PROTO)
3765 /*
3766  * Obtain the current messages language.  Used to set the default for
3767  * 'helplang'.  May return NULL or an empty string.
3768  */
3769     char_u *
3770 get_mess_lang()
3771 {
3772     char_u *p;
3773 
3774 # if (defined(HAVE_LOCALE_H) || defined(X_LOCALE))
3775 #  if defined(LC_MESSAGES)
3776     p = (char_u *)get_locale_val(LC_MESSAGES);
3777 #  else
3778     /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
3779      * may be set to the LCID number. */
3780     p = (char_u *)get_locale_val(LC_ALL);
3781 #  endif
3782 # else
3783     p = mch_getenv((char_u *)"LC_ALL");
3784     if (p == NULL || *p == NUL)
3785     {
3786 	p = mch_getenv((char_u *)"LC_MESSAGES");
3787 	if (p == NULL || *p == NUL)
3788 	    p = mch_getenv((char_u *)"LANG");
3789     }
3790 # endif
3791 # ifdef WIN32
3792     p = gettext_lang(p);
3793 # endif
3794     return p;
3795 }
3796 #endif
3797 
3798 /* Complicated #if; matches with where get_mess_env() is used below. */
3799 #if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3800 	    && defined(LC_MESSAGES))) \
3801 	|| ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3802 		&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) \
3803 		&& !defined(LC_MESSAGES))
3804 static char_u *get_mess_env __ARGS((void));
3805 
3806 /*
3807  * Get the language used for messages from the environment.
3808  */
3809     static char_u *
3810 get_mess_env()
3811 {
3812     char_u	*p;
3813 
3814     p = mch_getenv((char_u *)"LC_ALL");
3815     if (p == NULL || *p == NUL)
3816     {
3817 	p = mch_getenv((char_u *)"LC_MESSAGES");
3818 	if (p == NULL || *p == NUL)
3819 	{
3820 	    p = mch_getenv((char_u *)"LANG");
3821 	    if (p != NULL && VIM_ISDIGIT(*p))
3822 		p = NULL;		/* ignore something like "1043" */
3823 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3824 	    if (p == NULL || *p == NUL)
3825 		p = (char_u *)get_locale_val(LC_CTYPE);
3826 # endif
3827 	}
3828     }
3829     return p;
3830 }
3831 #endif
3832 
3833 #if defined(FEAT_EVAL) || defined(PROTO)
3834 
3835 /*
3836  * Set the "v:lang" variable according to the current locale setting.
3837  * Also do "v:lc_time"and "v:ctype".
3838  */
3839     void
3840 set_lang_var()
3841 {
3842     char_u	*loc;
3843 
3844 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3845     loc = (char_u *)get_locale_val(LC_CTYPE);
3846 # else
3847     /* setlocale() not supported: use the default value */
3848     loc = (char_u *)"C";
3849 # endif
3850     set_vim_var_string(VV_CTYPE, loc, -1);
3851 
3852     /* When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
3853      * back to LC_CTYPE if it's empty. */
3854 # if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) && defined(LC_MESSAGES)
3855     loc = (char_u *)get_locale_val(LC_MESSAGES);
3856 # else
3857     loc = get_mess_env();
3858 # endif
3859     set_vim_var_string(VV_LANG, loc, -1);
3860 
3861 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3862     loc = (char_u *)get_locale_val(LC_TIME);
3863 # endif
3864     set_vim_var_string(VV_LC_TIME, loc, -1);
3865 }
3866 #endif
3867 
3868 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3869 	&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
3870 /*
3871  * ":language":  Set the language (locale).
3872  */
3873     void
3874 ex_language(eap)
3875     exarg_T	*eap;
3876 {
3877     char	*loc;
3878     char_u	*p;
3879     char_u	*name;
3880     int		what = LC_ALL;
3881     char	*whatstr = "";
3882 #ifdef LC_MESSAGES
3883 # define VIM_LC_MESSAGES LC_MESSAGES
3884 #else
3885 # define VIM_LC_MESSAGES 6789
3886 #endif
3887 
3888     name = eap->arg;
3889 
3890     /* Check for "messages {name}", "ctype {name}" or "time {name}" argument.
3891      * Allow abbreviation, but require at least 3 characters to avoid
3892      * confusion with a two letter language name "me" or "ct". */
3893     p = skiptowhite(eap->arg);
3894     if ((*p == NUL || vim_iswhite(*p)) && p - eap->arg >= 3)
3895     {
3896 	if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0)
3897 	{
3898 	    what = VIM_LC_MESSAGES;
3899 	    name = skipwhite(p);
3900 	    whatstr = "messages ";
3901 	}
3902 	else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0)
3903 	{
3904 	    what = LC_CTYPE;
3905 	    name = skipwhite(p);
3906 	    whatstr = "ctype ";
3907 	}
3908 	else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0)
3909 	{
3910 	    what = LC_TIME;
3911 	    name = skipwhite(p);
3912 	    whatstr = "time ";
3913 	}
3914     }
3915 
3916     if (*name == NUL)
3917     {
3918 #ifndef LC_MESSAGES
3919 	if (what == VIM_LC_MESSAGES)
3920 	    p = get_mess_env();
3921 	else
3922 #endif
3923 	    p = (char_u *)setlocale(what, NULL);
3924 	if (p == NULL || *p == NUL)
3925 	    p = (char_u *)"Unknown";
3926 	smsg((char_u *)_("Current %slanguage: \"%s\""), whatstr, p);
3927     }
3928     else
3929     {
3930 #ifndef LC_MESSAGES
3931 	if (what == VIM_LC_MESSAGES)
3932 	    loc = "";
3933 	else
3934 #endif
3935 	    loc = setlocale(what, (char *)name);
3936 	if (loc == NULL)
3937 	    EMSG2(_("E197: Cannot set language to \"%s\""), name);
3938 	else
3939 	{
3940 #ifdef HAVE_NL_MSG_CAT_CNTR
3941 	    /* Need to do this for GNU gettext, otherwise cached translations
3942 	     * will be used again. */
3943 	    extern int _nl_msg_cat_cntr;
3944 
3945 	    ++_nl_msg_cat_cntr;
3946 #endif
3947 	    /* Reset $LC_ALL, otherwise it would overrule everyting. */
3948 	    vim_setenv((char_u *)"LC_ALL", (char_u *)"");
3949 
3950 	    if (what != LC_TIME)
3951 	    {
3952 		/* Tell gettext() what to translate to.  It apparently doesn't
3953 		 * use the currently effective locale.  Also do this when
3954 		 * FEAT_GETTEXT isn't defined, so that shell commands use this
3955 		 * value. */
3956 		if (what == LC_ALL)
3957 		{
3958 		    vim_setenv((char_u *)"LANG", name);
3959 # ifdef WIN32
3960 		    /* Apparently MS-Windows printf() may cause a crash when
3961 		     * we give it 8-bit text while it's expecting text in the
3962 		     * current locale.  This call avoids that. */
3963 		    setlocale(LC_CTYPE, "C");
3964 # endif
3965 		}
3966 		if (what != LC_CTYPE)
3967 		{
3968 		    char_u	*mname;
3969 #ifdef WIN32
3970 		    mname = gettext_lang(name);
3971 #else
3972 		    mname = name;
3973 #endif
3974 		    vim_setenv((char_u *)"LC_MESSAGES", mname);
3975 #ifdef FEAT_MULTI_LANG
3976 		    set_helplang_default(mname);
3977 #endif
3978 		}
3979 
3980 		/* Set $LC_CTYPE, because it overrules $LANG, and
3981 		 * gtk_set_locale() calls setlocale() again.  gnome_init()
3982 		 * sets $LC_CTYPE to "en_US" (that's a bug!). */
3983 		if (what != VIM_LC_MESSAGES)
3984 		    vim_setenv((char_u *)"LC_CTYPE", name);
3985 # ifdef FEAT_GUI_GTK
3986 		/* Let GTK know what locale we're using.  Not sure this is
3987 		 * really needed... */
3988 		if (gui.in_use)
3989 		    (void)gtk_set_locale();
3990 # endif
3991 	    }
3992 
3993 # ifdef FEAT_EVAL
3994 	    /* Set v:lang, v:lc_time and v:ctype to the final result. */
3995 	    set_lang_var();
3996 # endif
3997 	}
3998     }
3999 }
4000 
4001 # if defined(FEAT_CMDL_COMPL) || defined(PROTO)
4002 /*
4003  * Function given to ExpandGeneric() to obtain the possible arguments of the
4004  * ":language" command.
4005  */
4006 /*ARGSUSED*/
4007     char_u *
4008 get_lang_arg(xp, idx)
4009     expand_T	*xp;
4010     int		idx;
4011 {
4012     if (idx == 0)
4013 	return (char_u *)"messages";
4014     if (idx == 1)
4015 	return (char_u *)"ctype";
4016     if (idx == 2)
4017 	return (char_u *)"time";
4018     return NULL;
4019 }
4020 # endif
4021 
4022 #endif
4023