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