Merge branch 'vim' into feat/quickfix-title
[vim_extended.git] / src / ex_cmds2.c
blobfd628d606ad26ec782aba3294437b42faefa69e2
1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
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 */
11 * ex_cmds2.c: some more functions for command line commands
14 #if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64)
15 # include "vimio.h" /* for mch_open(), must be before vim.h */
16 #endif
18 #include "vim.h"
19 #include "version.h"
21 static void cmd_source __ARGS((char_u *fname, exarg_T *eap));
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
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;
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])
59 # ifdef FEAT_PROFILE
60 /* Struct used in sn_prl_ga for every line of a script. */
61 typedef struct sn_prl_S
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;
68 # define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
69 # endif
70 #endif
72 #if defined(FEAT_EVAL) || defined(PROTO)
73 static int debug_greedy = FALSE; /* batch mode debugging: don't save
74 and restore typeahead. */
77 * do_debug(): Debug mode.
78 * Repeatedly get Ex commands, until told to continue normal execution.
80 void
81 do_debug(cmd)
82 char_u *cmd;
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
109 #ifdef ALWAYS_USE_GUI
110 /* Can't do this when there is no terminal for input/output. */
111 if (!gui.in_use)
113 /* Break as soon as possible. */
114 debug_break_level = 9999;
115 return;
117 #endif
119 /* Make sure we are in raw mode and start termcap mode. Might have side
120 * effects... */
121 settmode(TMODE_RAW);
122 starttermcap();
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 */
132 State = NORMAL;
133 #ifdef FEAT_SNIFF
134 want_sniff_request = 0; /* No K_SNIFF wanted */
135 #endif
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);
147 * Repeat getting a command and executing it.
149 for (;;)
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)
167 save_typeahead(&typeaheadbuf);
168 typeahead_saved = TRUE;
169 save_ignore_script = ignore_script;
170 ignore_script = TRUE;
173 cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
175 if (typeahead_saved)
177 restore_typeahead(&typeaheadbuf);
178 ignore_script = save_ignore_script;
180 # ifdef FEAT_EX_EXTRA
181 ex_normal_busy = save_ex_normal_busy;
182 # endif
184 cmdline_row = msg_row;
185 if (cmdline != NULL)
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)
193 switch (*p)
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;
215 if (last_cmd != 0)
217 /* Check that the tail matches. */
218 ++p;
219 while (*p != NUL && *p == *tail)
221 ++p;
222 ++tail;
224 if (ASCII_ISALPHA(*p))
225 last_cmd = 0;
229 if (last_cmd != 0)
231 /* Execute debug command: decided where to break next and
232 * return. */
233 switch (last_cmd)
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;
258 break;
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;
268 vim_free(cmdline);
270 lines_left = Rows - 1;
272 vim_free(cmdline);
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;
287 /* Only print the message again when typing a command before coming back
288 * here. */
289 debug_did_msg = TRUE;
293 * ":debug".
295 void
296 ex_debug(eap)
297 exarg_T *eap;
299 int debug_break_level_save = debug_break_level;
301 debug_break_level = 9999;
302 do_cmdline_cmd(eap->arg);
303 debug_break_level = debug_break_level_save;
306 static char_u *debug_breakpoint_name = NULL;
307 static linenr_T debug_breakpoint_lnum;
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().
316 static int debug_skipped;
317 static char_u *debug_skipped_name;
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.
326 void
327 dbg_check_breakpoint(eap)
328 exarg_T *eap;
330 char_u *p;
332 debug_skipped = FALSE;
333 if (debug_breakpoint_name != NULL)
335 if (!eap->skip)
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"),
346 debug_breakpoint_name + (*p == NUL ? 0 : 3),
347 (long)debug_breakpoint_lnum);
348 debug_breakpoint_name = NULL;
349 do_debug(eap->cmd);
351 else
353 debug_skipped = TRUE;
354 debug_skipped_name = debug_breakpoint_name;
355 debug_breakpoint_name = NULL;
358 else if (ex_nesting_level <= debug_break_level)
360 if (!eap->skip)
361 do_debug(eap->cmd);
362 else
364 debug_skipped = TRUE;
365 debug_skipped_name = NULL;
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.
375 dbg_check_skipped(eap)
376 exarg_T *eap;
378 int prev_got_int;
380 if (debug_skipped)
383 * Save the value of got_int and reset it. We don't want a previous
384 * interruption cause flushing the input buffer.
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;
396 return FALSE;
400 * The list of breakpoints: dbg_breakp.
401 * This is a grow-array of structs.
403 struct debuggy
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 */
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 */
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
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));
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.
434 static int
435 dbg_parsearg(arg, gap)
436 char_u *arg;
437 garray_T *gap; /* either &dbg_breakp or &prof_ga */
439 char_u *p = arg;
440 char_u *q;
441 struct debuggy *bp;
442 int here = FALSE;
444 if (ga_grow(gap, 1) == FAIL)
445 return FAIL;
446 bp = &DEBUGGY(gap, gap->ga_len);
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)
459 if (curbuf->b_ffname == NULL)
461 EMSG(_(e_noname));
462 return FAIL;
464 bp->dbg_type = DBG_FILE;
465 here = TRUE;
467 else
469 EMSG2(_(e_invarg2), p);
470 return FAIL;
472 p = skipwhite(p + 4);
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))
483 bp->dbg_lnum = getdigits(&p);
484 p = skipwhite(p);
486 else
487 bp->dbg_lnum = 0;
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))
494 EMSG2(_(e_invarg2), arg);
495 return FAIL;
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
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 != '*')
524 bp->dbg_name = fix_fname(p);
525 vim_free(p);
527 else
528 bp->dbg_name = p;
531 if (bp->dbg_name == NULL)
532 return FAIL;
533 return OK;
537 * ":breakadd".
539 void
540 ex_breakadd(eap)
541 exarg_T *eap;
543 struct debuggy *bp;
544 char_u *pat;
545 garray_T *gap;
547 gap = &dbg_breakp;
548 #ifdef FEAT_PROFILE
549 if (eap->cmdidx == CMD_profile)
550 gap = &prof_ga;
551 #endif
553 if (dbg_parsearg(eap->arg, gap) == OK)
555 bp = &DEBUGGY(gap, gap->ga_len);
556 bp->dbg_forceit = eap->forceit;
558 pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, FALSE);
559 if (pat != NULL)
561 bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
562 vim_free(pat);
564 if (pat == NULL || bp->dbg_prog == NULL)
565 vim_free(bp->dbg_name);
566 else
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
574 DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
575 ++debug_tick;
577 ++gap->ga_len;
583 * ":debuggreedy".
585 void
586 ex_debuggreedy(eap)
587 exarg_T *eap;
589 if (eap->addr_count == 0 || eap->line2 != 0)
590 debug_greedy = TRUE;
591 else
592 debug_greedy = FALSE;
596 * ":breakdel" and ":profdel".
598 void
599 ex_breakdel(eap)
600 exarg_T *eap;
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;
610 gap = &dbg_breakp;
611 #ifdef FEAT_PROFILE
612 if (eap->cmdidx == CMD_profdel)
613 gap = &prof_ga;
614 #endif
616 if (vim_isdigit(*eap->arg))
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)
623 todel = i;
624 break;
627 else if (*eap->arg == '*')
629 todel = 0;
630 del_all = TRUE;
632 else
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)
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))))
648 todel = i;
649 best_lnum = bpi->dbg_lnum;
652 vim_free(bp->dbg_name);
655 if (todel < 0)
656 EMSG2(_("E161: Breakpoint not found: %s"), eap->arg);
657 else
659 while (gap->ga_len > 0)
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;
675 /* If all breakpoints were removed clear the array. */
676 if (gap->ga_len == 0)
677 ga_clear(gap);
682 * ":breaklist".
684 void
685 ex_breaklist(eap)
686 exarg_T *eap UNUSED;
688 struct debuggy *bp;
689 int i;
691 if (dbg_breakp.ga_len == 0)
692 MSG(_("No breakpoints defined"));
693 else
694 for (i = 0; i < dbg_breakp.ga_len; ++i)
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);
706 * Find a breakpoint for a function or sourced file.
707 * Returns line number at which to break; zero when no matching breakpoint.
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 */
715 return debuggy_find(file, fname, after, &dbg_breakp, NULL);
718 #if defined(FEAT_PROFILE) || defined(PROTO)
720 * Return TRUE if profiling is on for a function or sourced file.
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 */
728 return (debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
729 != (linenr_T)0);
731 #endif
734 * Common code for dbg_find_breakpoint() and has_profiling().
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 */
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;
751 /* Return quickly when there are no breakpoints. */
752 if (gap->ga_len == 0)
753 return (linenr_T)0;
755 /* Replace K_SNR in function name with "<SNR>". */
756 if (!file && fname[0] == K_SPECIAL)
758 name = alloc((unsigned)STRLEN(fname) + 3);
759 if (name == NULL)
760 name = fname;
761 else
763 STRCPY(name, "<SNR>");
764 STRCPY(name + 5, fname + 3);
768 for (i = 0; i < gap->ga_len; ++i)
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)))))
779 regmatch.regprog = bp->dbg_prog;
780 regmatch.rm_ic = FALSE;
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.
786 prev_got_int = got_int;
787 got_int = FALSE;
788 if (vim_regexec(&regmatch, name, (colnr_T)0))
790 lnum = bp->dbg_lnum;
791 if (fp != NULL)
792 *fp = bp->dbg_forceit;
794 got_int |= prev_got_int;
797 if (name != fname)
798 vim_free(name);
800 return lnum;
804 * Called when a breakpoint was encountered.
806 void
807 dbg_breakpoint(name, lnum)
808 char_u *name;
809 linenr_T lnum;
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;
817 # if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO)
819 * Store the current time in "tm".
821 void
822 profile_start(tm)
823 proftime_T *tm;
825 # ifdef WIN3264
826 QueryPerformanceCounter(tm);
827 # else
828 gettimeofday(tm, NULL);
829 # endif
833 * Compute the elapsed time from "tm" till now and store in "tm".
835 void
836 profile_end(tm)
837 proftime_T *tm;
839 proftime_T now;
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)
850 tm->tv_usec += 1000000;
851 --tm->tv_sec;
853 # endif
857 * Subtract the time "tm2" from "tm".
859 void
860 profile_sub(tm, tm2)
861 proftime_T *tm, *tm2;
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)
870 tm->tv_usec += 1000000;
871 --tm->tv_sec;
873 # endif
877 * Return a string that represents the time in "tm".
878 * Uses a static buffer!
880 char *
881 profile_msg(tm)
882 proftime_T *tm;
884 static char buf[50];
886 # ifdef WIN3264
887 LARGE_INTEGER fr;
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;
898 * Put the time "msec" past now in "tm".
900 void
901 profile_setlimit(msec, tm)
902 long msec;
903 proftime_T *tm;
905 if (msec <= 0) /* no limit */
906 profile_zero(tm);
907 else
909 # ifdef WIN3264
910 LARGE_INTEGER fr;
912 QueryPerformanceCounter(tm);
913 QueryPerformanceFrequency(&fr);
914 tm->QuadPart += (LONGLONG)((double)msec / 1000.0 * (double)fr.QuadPart);
915 # else
916 long usec;
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
927 * Return TRUE if the current time is past "tm".
930 profile_passed_limit(tm)
931 proftime_T *tm;
933 proftime_T now;
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
950 * Set the time in "tm" to zero.
952 void
953 profile_zero(tm)
954 proftime_T *tm;
956 # ifdef WIN3264
957 tm->QuadPart = 0;
958 # else
959 tm->tv_usec = 0;
960 tm->tv_sec = 0;
961 # endif
964 # endif /* FEAT_PROFILE || FEAT_RELTIME */
966 # if defined(FEAT_PROFILE) || defined(PROTO)
968 * Functions for profiling.
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;
975 * Add the time "tm2" to "tm".
977 void
978 profile_add(tm, tm2)
979 proftime_T *tm, *tm2;
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)
988 tm->tv_usec -= 1000000;
989 ++tm->tv_sec;
991 # endif
995 * Add the "self" time from the total time and the children's time.
997 void
998 profile_self(self, total, children)
999 proftime_T *self, *total, *children;
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);
1017 * Get the current waittime.
1019 void
1020 profile_get_wait(tm)
1021 proftime_T *tm;
1023 *tm = prof_wait_time;
1027 * Subtract the passed waittime since "tm" from "tma".
1029 void
1030 profile_sub_wait(tm, tma)
1031 proftime_T *tm, *tma;
1033 proftime_T tm3 = prof_wait_time;
1035 profile_sub(&tm3, tm);
1036 profile_sub(tma, &tm3);
1040 * Return TRUE if "tm1" and "tm2" are equal.
1043 profile_equal(tm1, tm2)
1044 proftime_T *tm1, *tm2;
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
1054 * Return <0, 0 or >0 if "tm1" < "tm2", "tm1" == "tm2" or "tm1" > "tm2"
1057 profile_cmp(tm1, tm2)
1058 proftime_T *tm1, *tm2;
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
1069 static char_u *profile_fname = NULL;
1070 static proftime_T pause_time;
1073 * ":profile cmd args"
1075 void
1076 ex_profile(eap)
1077 exarg_T *eap;
1079 char_u *e;
1080 int len;
1082 e = skiptowhite(eap->arg);
1083 len = (int)(e - eap->arg);
1084 e = skipwhite(e);
1086 if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL)
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);
1094 else if (do_profiling == PROF_NONE)
1095 EMSG(_("E750: First use :profile start <fname>"));
1096 else if (STRCMP(eap->arg, "pause") == 0)
1098 if (do_profiling == PROF_YES)
1099 profile_start(&pause_time);
1100 do_profiling = PROF_PAUSED;
1102 else if (STRCMP(eap->arg, "continue") == 0)
1104 if (do_profiling == PROF_PAUSED)
1106 profile_end(&pause_time);
1107 profile_add(&prof_wait_time, &pause_time);
1109 do_profiling = PROF_YES;
1111 else
1113 /* The rest is similar to ":breakadd". */
1114 ex_breakadd(eap);
1119 * Dump the profiling info.
1121 void
1122 profile_dump()
1124 FILE *fd;
1126 if (profile_fname != NULL)
1128 fd = mch_fopen((char *)profile_fname, "w");
1129 if (fd == NULL)
1130 EMSG2(_(e_notopen), profile_fname);
1131 else
1133 script_dump_profile(fd);
1134 func_dump_profile(fd);
1135 fclose(fd);
1141 * Start profiling script "fp".
1143 static void
1144 script_do_profile(si)
1145 scriptitem_T *si;
1147 si->sn_pr_count = 0;
1148 profile_zero(&si->sn_pr_total);
1149 profile_zero(&si->sn_pr_self);
1151 ga_init2(&si->sn_prl_ga, sizeof(sn_prl_T), 100);
1152 si->sn_prl_idx = -1;
1153 si->sn_prof_on = TRUE;
1154 si->sn_pr_nest = 0;
1158 * save time when starting to invoke another script or function.
1160 void
1161 script_prof_save(tm)
1162 proftime_T *tm; /* place to store wait time */
1164 scriptitem_T *si;
1166 if (current_SID > 0 && current_SID <= script_items.ga_len)
1168 si = &SCRIPT_ITEM(current_SID);
1169 if (si->sn_prof_on && si->sn_pr_nest++ == 0)
1170 profile_start(&si->sn_pr_child);
1172 profile_get_wait(tm);
1176 * Count time spent in children after invoking another script or function.
1178 void
1179 script_prof_restore(tm)
1180 proftime_T *tm;
1182 scriptitem_T *si;
1184 if (current_SID > 0 && current_SID <= script_items.ga_len)
1186 si = &SCRIPT_ITEM(current_SID);
1187 if (si->sn_prof_on && --si->sn_pr_nest == 0)
1189 profile_end(&si->sn_pr_child);
1190 profile_sub_wait(tm, &si->sn_pr_child); /* don't count wait time */
1191 profile_add(&si->sn_pr_children, &si->sn_pr_child);
1192 profile_add(&si->sn_prl_children, &si->sn_pr_child);
1197 static proftime_T inchar_time;
1200 * Called when starting to wait for the user to type a character.
1202 void
1203 prof_inchar_enter()
1205 profile_start(&inchar_time);
1209 * Called when finished waiting for the user to type a character.
1211 void
1212 prof_inchar_exit()
1214 profile_end(&inchar_time);
1215 profile_add(&prof_wait_time, &inchar_time);
1219 * Dump the profiling results for all scripts in file "fd".
1221 static void
1222 script_dump_profile(fd)
1223 FILE *fd;
1225 int id;
1226 scriptitem_T *si;
1227 int i;
1228 FILE *sfd;
1229 sn_prl_T *pp;
1231 for (id = 1; id <= script_items.ga_len; ++id)
1233 si = &SCRIPT_ITEM(id);
1234 if (si->sn_prof_on)
1236 fprintf(fd, "SCRIPT %s\n", si->sn_name);
1237 if (si->sn_pr_count == 1)
1238 fprintf(fd, "Sourced 1 time\n");
1239 else
1240 fprintf(fd, "Sourced %d times\n", si->sn_pr_count);
1241 fprintf(fd, "Total time: %s\n", profile_msg(&si->sn_pr_total));
1242 fprintf(fd, " Self time: %s\n", profile_msg(&si->sn_pr_self));
1243 fprintf(fd, "\n");
1244 fprintf(fd, "count total (s) self (s)\n");
1246 sfd = mch_fopen((char *)si->sn_name, "r");
1247 if (sfd == NULL)
1248 fprintf(fd, "Cannot open file!\n");
1249 else
1251 for (i = 0; i < si->sn_prl_ga.ga_len; ++i)
1253 if (vim_fgets(IObuff, IOSIZE, sfd))
1254 break;
1255 pp = &PRL_ITEM(si, i);
1256 if (pp->snp_count > 0)
1258 fprintf(fd, "%5d ", pp->snp_count);
1259 if (profile_equal(&pp->sn_prl_total, &pp->sn_prl_self))
1260 fprintf(fd, " ");
1261 else
1262 fprintf(fd, "%s ", profile_msg(&pp->sn_prl_total));
1263 fprintf(fd, "%s ", profile_msg(&pp->sn_prl_self));
1265 else
1266 fprintf(fd, " ");
1267 fprintf(fd, "%s", IObuff);
1269 fclose(sfd);
1271 fprintf(fd, "\n");
1277 * Return TRUE when a function defined in the current script should be
1278 * profiled.
1281 prof_def_func()
1283 if (current_SID > 0)
1284 return SCRIPT_ITEM(current_SID).sn_pr_force;
1285 return FALSE;
1288 # endif
1289 #endif
1292 * If 'autowrite' option set, try to write the file.
1293 * Careful: autocommands may make "buf" invalid!
1295 * return FAIL for failure, OK otherwise
1298 autowrite(buf, forceit)
1299 buf_T *buf;
1300 int forceit;
1302 int r;
1304 if (!(p_aw || p_awa) || !p_write
1305 #ifdef FEAT_QUICKFIX
1306 /* never autowrite a "nofile" or "nowrite" buffer */
1307 || bt_dontwrite(buf)
1308 #endif
1309 || (!forceit && buf->b_p_ro) || buf->b_ffname == NULL)
1310 return FAIL;
1311 r = buf_write_all(buf, forceit);
1313 /* Writing may succeed but the buffer still changed, e.g., when there is a
1314 * conversion error. We do want to return FAIL then. */
1315 if (buf_valid(buf) && bufIsChanged(buf))
1316 r = FAIL;
1317 return r;
1321 * flush all buffers, except the ones that are readonly
1323 void
1324 autowrite_all()
1326 buf_T *buf;
1328 if (!(p_aw || p_awa) || !p_write)
1329 return;
1330 for (buf = firstbuf; buf; buf = buf->b_next)
1331 if (bufIsChanged(buf) && !buf->b_p_ro)
1333 (void)buf_write_all(buf, FALSE);
1334 #ifdef FEAT_AUTOCMD
1335 /* an autocommand may have deleted the buffer */
1336 if (!buf_valid(buf))
1337 buf = firstbuf;
1338 #endif
1343 * return TRUE if buffer was changed and cannot be abandoned.
1346 check_changed(buf, checkaw, mult_win, forceit, allbuf)
1347 buf_T *buf;
1348 int checkaw; /* do autowrite if buffer was changed */
1349 int mult_win; /* check also when several wins for the buf */
1350 int forceit;
1351 int allbuf UNUSED; /* may write all buffers */
1353 if ( !forceit
1354 && bufIsChanged(buf)
1355 && (mult_win || buf->b_nwindows <= 1)
1356 && (!checkaw || autowrite(buf, forceit) == FAIL))
1358 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1359 if ((p_confirm || cmdmod.confirm) && p_write)
1361 buf_T *buf2;
1362 int count = 0;
1364 if (allbuf)
1365 for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1366 if (bufIsChanged(buf2)
1367 && (buf2->b_ffname != NULL
1368 # ifdef FEAT_BROWSE
1369 || cmdmod.browse
1370 # endif
1372 ++count;
1373 # ifdef FEAT_AUTOCMD
1374 if (!buf_valid(buf))
1375 /* Autocommand deleted buffer, oops! It's not changed now. */
1376 return FALSE;
1377 # endif
1378 dialog_changed(buf, count > 1);
1379 # ifdef FEAT_AUTOCMD
1380 if (!buf_valid(buf))
1381 /* Autocommand deleted buffer, oops! It's not changed now. */
1382 return FALSE;
1383 # endif
1384 return bufIsChanged(buf);
1386 #endif
1387 EMSG(_(e_nowrtmsg));
1388 return TRUE;
1390 return FALSE;
1393 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO)
1395 #if defined(FEAT_BROWSE) || defined(PROTO)
1397 * When wanting to write a file without a file name, ask the user for a name.
1399 void
1400 browse_save_fname(buf)
1401 buf_T *buf;
1403 if (buf->b_fname == NULL)
1405 char_u *fname;
1407 fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"),
1408 NULL, NULL, NULL, NULL, buf);
1409 if (fname != NULL)
1411 if (setfname(buf, fname, NULL, TRUE) == OK)
1412 buf->b_flags |= BF_NOTEDITED;
1413 vim_free(fname);
1417 #endif
1420 * Ask the user what to do when abondoning a changed buffer.
1421 * Must check 'write' option first!
1423 void
1424 dialog_changed(buf, checkall)
1425 buf_T *buf;
1426 int checkall; /* may abandon all changed buffers */
1428 char_u buff[IOSIZE];
1429 int ret;
1430 buf_T *buf2;
1432 dialog_msg(buff, _("Save changes to \"%s\"?"),
1433 (buf->b_fname != NULL) ?
1434 buf->b_fname : (char_u *)_("Untitled"));
1435 if (checkall)
1436 ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
1437 else
1438 ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
1440 if (ret == VIM_YES)
1442 #ifdef FEAT_BROWSE
1443 /* May get file name, when there is none */
1444 browse_save_fname(buf);
1445 #endif
1446 if (buf->b_fname != NULL) /* didn't hit Cancel */
1447 (void)buf_write_all(buf, FALSE);
1449 else if (ret == VIM_NO)
1451 unchanged(buf, TRUE);
1453 else if (ret == VIM_ALL)
1456 * Write all modified files that can be written.
1457 * Skip readonly buffers, these need to be confirmed
1458 * individually.
1460 for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1462 if (bufIsChanged(buf2)
1463 && (buf2->b_ffname != NULL
1464 #ifdef FEAT_BROWSE
1465 || cmdmod.browse
1466 #endif
1468 && !buf2->b_p_ro)
1470 #ifdef FEAT_BROWSE
1471 /* May get file name, when there is none */
1472 browse_save_fname(buf2);
1473 #endif
1474 if (buf2->b_fname != NULL) /* didn't hit Cancel */
1475 (void)buf_write_all(buf2, FALSE);
1476 #ifdef FEAT_AUTOCMD
1477 /* an autocommand may have deleted the buffer */
1478 if (!buf_valid(buf2))
1479 buf2 = firstbuf;
1480 #endif
1484 else if (ret == VIM_DISCARDALL)
1487 * mark all buffers as unchanged
1489 for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1490 unchanged(buf2, TRUE);
1493 #endif
1496 * Return TRUE if the buffer "buf" can be abandoned, either by making it
1497 * hidden, autowriting it or unloading it.
1500 can_abandon(buf, forceit)
1501 buf_T *buf;
1502 int forceit;
1504 return ( P_HID(buf)
1505 || !bufIsChanged(buf)
1506 || buf->b_nwindows > 1
1507 || autowrite(buf, forceit) == OK
1508 || forceit);
1512 * Return TRUE if any buffer was changed and cannot be abandoned.
1513 * That changed buffer becomes the current buffer.
1516 check_changed_any(hidden)
1517 int hidden; /* Only check hidden buffers */
1519 buf_T *buf;
1520 int save;
1521 #ifdef FEAT_WINDOWS
1522 win_T *wp;
1523 #endif
1524 char_u *bname;
1526 for (;;)
1528 /* check curbuf first: if it was changed we can't abandon it */
1529 if (!hidden && curbufIsChanged())
1530 buf = curbuf;
1531 else
1533 for (buf = firstbuf; buf != NULL; buf = buf->b_next)
1534 if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf))
1535 break;
1537 if (buf == NULL) /* No buffers changed */
1538 return FALSE;
1540 /* Try auto-writing the buffer. If this fails but the buffer no
1541 * longer exists it's not changed, that's OK. */
1542 if (check_changed(buf, p_awa, TRUE, FALSE, TRUE) && buf_valid(buf))
1543 break; /* didn't save - still changes */
1546 exiting = FALSE;
1547 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1549 * When ":confirm" used, don't give an error message.
1551 if (!(p_confirm || cmdmod.confirm))
1552 #endif
1554 /* There must be a wait_return for this message, do_buffer()
1555 * may cause a redraw. But wait_return() is a no-op when vgetc()
1556 * is busy (Quit used from window menu), then make sure we don't
1557 * cause a scroll up. */
1558 if (vgetc_busy > 0)
1560 msg_row = cmdline_row;
1561 msg_col = 0;
1562 msg_didout = FALSE;
1564 if (EMSG2(_("E162: No write since last change for buffer \"%s\""),
1565 (bname = (char_u *)buf_spname(buf)) != NULL ? bname :
1566 buf->b_fname))
1568 save = no_wait_return;
1569 no_wait_return = FALSE;
1570 wait_return(FALSE);
1571 no_wait_return = save;
1573 vim_free(bname);
1576 #ifdef FEAT_WINDOWS
1577 /* Try to find a window that contains the buffer. */
1578 if (buf != curbuf)
1579 for (wp = firstwin; wp != NULL; wp = wp->w_next)
1580 if (wp->w_buffer == buf)
1582 win_goto(wp);
1583 # ifdef FEAT_AUTOCMD
1584 /* Paranoia: did autocms wipe out the buffer with changes? */
1585 if (!buf_valid(buf))
1586 return TRUE;
1587 # endif
1588 break;
1590 #endif
1592 /* Open the changed buffer in the current window. */
1593 if (buf != curbuf)
1594 set_curbuf(buf, DOBUF_GOTO);
1596 return TRUE;
1600 * return FAIL if there is no file name, OK if there is one
1601 * give error message for FAIL
1604 check_fname()
1606 if (curbuf->b_ffname == NULL)
1608 EMSG(_(e_noname));
1609 return FAIL;
1611 return OK;
1615 * flush the contents of a buffer, unless it has no file name
1617 * return FAIL for failure, OK otherwise
1620 buf_write_all(buf, forceit)
1621 buf_T *buf;
1622 int forceit;
1624 int retval;
1625 #ifdef FEAT_AUTOCMD
1626 buf_T *old_curbuf = curbuf;
1627 #endif
1629 retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
1630 (linenr_T)1, buf->b_ml.ml_line_count, NULL,
1631 FALSE, forceit, TRUE, FALSE));
1632 #ifdef FEAT_AUTOCMD
1633 if (curbuf != old_curbuf)
1635 msg_source(hl_attr(HLF_W));
1636 MSG(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
1638 #endif
1639 return retval;
1643 * Code to handle the argument list.
1646 static char_u *do_one_arg __ARGS((char_u *str));
1647 static int do_arglist __ARGS((char_u *str, int what, int after));
1648 static void alist_check_arg_idx __ARGS((void));
1649 static int editing_arg_idx __ARGS((win_T *win));
1650 #ifdef FEAT_LISTCMDS
1651 static int alist_add_list __ARGS((int count, char_u **files, int after));
1652 #endif
1653 #define AL_SET 1
1654 #define AL_ADD 2
1655 #define AL_DEL 3
1658 * Isolate one argument, taking backticks.
1659 * Changes the argument in-place, puts a NUL after it. Backticks remain.
1660 * Return a pointer to the start of the next argument.
1662 static char_u *
1663 do_one_arg(str)
1664 char_u *str;
1666 char_u *p;
1667 int inbacktick;
1669 inbacktick = FALSE;
1670 for (p = str; *str; ++str)
1672 /* When the backslash is used for escaping the special meaning of a
1673 * character we need to keep it until wildcard expansion. */
1674 if (rem_backslash(str))
1676 *p++ = *str++;
1677 *p++ = *str;
1679 else
1681 /* An item ends at a space not in backticks */
1682 if (!inbacktick && vim_isspace(*str))
1683 break;
1684 if (*str == '`')
1685 inbacktick ^= TRUE;
1686 *p++ = *str;
1689 str = skipwhite(str);
1690 *p = NUL;
1692 return str;
1696 * Separate the arguments in "str" and return a list of pointers in the
1697 * growarray "gap".
1700 get_arglist(gap, str)
1701 garray_T *gap;
1702 char_u *str;
1704 ga_init2(gap, (int)sizeof(char_u *), 20);
1705 while (*str != NUL)
1707 if (ga_grow(gap, 1) == FAIL)
1709 ga_clear(gap);
1710 return FAIL;
1712 ((char_u **)gap->ga_data)[gap->ga_len++] = str;
1714 /* Isolate one argument, change it in-place, put a NUL after it. */
1715 str = do_one_arg(str);
1717 return OK;
1720 #if defined(FEAT_QUICKFIX) || defined(FEAT_SYN_HL) || defined(PROTO)
1722 * Parse a list of arguments (file names), expand them and return in
1723 * "fnames[fcountp]".
1724 * Return FAIL or OK.
1727 get_arglist_exp(str, fcountp, fnamesp)
1728 char_u *str;
1729 int *fcountp;
1730 char_u ***fnamesp;
1732 garray_T ga;
1733 int i;
1735 if (get_arglist(&ga, str) == FAIL)
1736 return FAIL;
1737 i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
1738 fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
1739 ga_clear(&ga);
1740 return i;
1742 #endif
1744 #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
1746 * Redefine the argument list.
1748 void
1749 set_arglist(str)
1750 char_u *str;
1752 do_arglist(str, AL_SET, 0);
1754 #endif
1757 * "what" == AL_SET: Redefine the argument list to 'str'.
1758 * "what" == AL_ADD: add files in 'str' to the argument list after "after".
1759 * "what" == AL_DEL: remove files in 'str' from the argument list.
1761 * Return FAIL for failure, OK otherwise.
1763 static int
1764 do_arglist(str, what, after)
1765 char_u *str;
1766 int what UNUSED;
1767 int after UNUSED; /* 0 means before first one */
1769 garray_T new_ga;
1770 int exp_count;
1771 char_u **exp_files;
1772 int i;
1773 #ifdef FEAT_LISTCMDS
1774 char_u *p;
1775 int match;
1776 #endif
1779 * Collect all file name arguments in "new_ga".
1781 if (get_arglist(&new_ga, str) == FAIL)
1782 return FAIL;
1784 #ifdef FEAT_LISTCMDS
1785 if (what == AL_DEL)
1787 regmatch_T regmatch;
1788 int didone;
1791 * Delete the items: use each item as a regexp and find a match in the
1792 * argument list.
1794 #ifdef CASE_INSENSITIVE_FILENAME
1795 regmatch.rm_ic = TRUE; /* Always ignore case */
1796 #else
1797 regmatch.rm_ic = FALSE; /* Never ignore case */
1798 #endif
1799 for (i = 0; i < new_ga.ga_len && !got_int; ++i)
1801 p = ((char_u **)new_ga.ga_data)[i];
1802 p = file_pat_to_reg_pat(p, NULL, NULL, FALSE);
1803 if (p == NULL)
1804 break;
1805 regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
1806 if (regmatch.regprog == NULL)
1808 vim_free(p);
1809 break;
1812 didone = FALSE;
1813 for (match = 0; match < ARGCOUNT; ++match)
1814 if (vim_regexec(&regmatch, alist_name(&ARGLIST[match]),
1815 (colnr_T)0))
1817 didone = TRUE;
1818 vim_free(ARGLIST[match].ae_fname);
1819 mch_memmove(ARGLIST + match, ARGLIST + match + 1,
1820 (ARGCOUNT - match - 1) * sizeof(aentry_T));
1821 --ALIST(curwin)->al_ga.ga_len;
1822 if (curwin->w_arg_idx > match)
1823 --curwin->w_arg_idx;
1824 --match;
1827 vim_free(regmatch.regprog);
1828 vim_free(p);
1829 if (!didone)
1830 EMSG2(_(e_nomatch2), ((char_u **)new_ga.ga_data)[i]);
1832 ga_clear(&new_ga);
1834 else
1835 #endif
1837 i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
1838 &exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND);
1839 ga_clear(&new_ga);
1840 if (i == FAIL)
1841 return FAIL;
1842 if (exp_count == 0)
1844 EMSG(_(e_nomatch));
1845 return FAIL;
1848 #ifdef FEAT_LISTCMDS
1849 if (what == AL_ADD)
1851 (void)alist_add_list(exp_count, exp_files, after);
1852 vim_free(exp_files);
1854 else /* what == AL_SET */
1855 #endif
1856 alist_set(ALIST(curwin), exp_count, exp_files, FALSE, NULL, 0);
1859 alist_check_arg_idx();
1861 return OK;
1865 * Check the validity of the arg_idx for each other window.
1867 static void
1868 alist_check_arg_idx()
1870 #ifdef FEAT_WINDOWS
1871 win_T *win;
1872 tabpage_T *tp;
1874 FOR_ALL_TAB_WINDOWS(tp, win)
1875 if (win->w_alist == curwin->w_alist)
1876 check_arg_idx(win);
1877 #else
1878 check_arg_idx(curwin);
1879 #endif
1883 * Return TRUE if window "win" is editing then file at the current argument
1884 * index.
1886 static int
1887 editing_arg_idx(win)
1888 win_T *win;
1890 return !(win->w_arg_idx >= WARGCOUNT(win)
1891 || (win->w_buffer->b_fnum
1892 != WARGLIST(win)[win->w_arg_idx].ae_fnum
1893 && (win->w_buffer->b_ffname == NULL
1894 || !(fullpathcmp(
1895 alist_name(&WARGLIST(win)[win->w_arg_idx]),
1896 win->w_buffer->b_ffname, TRUE) & FPC_SAME))));
1900 * Check if window "win" is editing the w_arg_idx file in its argument list.
1902 void
1903 check_arg_idx(win)
1904 win_T *win;
1906 if (WARGCOUNT(win) > 1 && !editing_arg_idx(win))
1908 /* We are not editing the current entry in the argument list.
1909 * Set "arg_had_last" if we are editing the last one. */
1910 win->w_arg_idx_invalid = TRUE;
1911 if (win->w_arg_idx != WARGCOUNT(win) - 1
1912 && arg_had_last == FALSE
1913 #ifdef FEAT_WINDOWS
1914 && ALIST(win) == &global_alist
1915 #endif
1916 && GARGCOUNT > 0
1917 && win->w_arg_idx < GARGCOUNT
1918 && (win->w_buffer->b_fnum == GARGLIST[GARGCOUNT - 1].ae_fnum
1919 || (win->w_buffer->b_ffname != NULL
1920 && (fullpathcmp(alist_name(&GARGLIST[GARGCOUNT - 1]),
1921 win->w_buffer->b_ffname, TRUE) & FPC_SAME))))
1922 arg_had_last = TRUE;
1924 else
1926 /* We are editing the current entry in the argument list.
1927 * Set "arg_had_last" if it's also the last one */
1928 win->w_arg_idx_invalid = FALSE;
1929 if (win->w_arg_idx == WARGCOUNT(win) - 1
1930 #ifdef FEAT_WINDOWS
1931 && win->w_alist == &global_alist
1932 #endif
1934 arg_had_last = TRUE;
1939 * ":args", ":argslocal" and ":argsglobal".
1941 void
1942 ex_args(eap)
1943 exarg_T *eap;
1945 int i;
1947 if (eap->cmdidx != CMD_args)
1949 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
1950 alist_unlink(ALIST(curwin));
1951 if (eap->cmdidx == CMD_argglobal)
1952 ALIST(curwin) = &global_alist;
1953 else /* eap->cmdidx == CMD_arglocal */
1954 alist_new();
1955 #else
1956 ex_ni(eap);
1957 return;
1958 #endif
1961 if (!ends_excmd(*eap->arg))
1964 * ":args file ..": define new argument list, handle like ":next"
1965 * Also for ":argslocal file .." and ":argsglobal file ..".
1967 ex_next(eap);
1969 else
1970 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
1971 if (eap->cmdidx == CMD_args)
1972 #endif
1975 * ":args": list arguments.
1977 if (ARGCOUNT > 0)
1979 /* Overwrite the command, for a short list there is no scrolling
1980 * required and no wait_return(). */
1981 gotocmdline(TRUE);
1982 for (i = 0; i < ARGCOUNT; ++i)
1984 if (i == curwin->w_arg_idx)
1985 msg_putchar('[');
1986 msg_outtrans(alist_name(&ARGLIST[i]));
1987 if (i == curwin->w_arg_idx)
1988 msg_putchar(']');
1989 msg_putchar(' ');
1993 #if defined(FEAT_WINDOWS) && defined(FEAT_LISTCMDS)
1994 else if (eap->cmdidx == CMD_arglocal)
1996 garray_T *gap = &curwin->w_alist->al_ga;
1999 * ":argslocal": make a local copy of the global argument list.
2001 if (ga_grow(gap, GARGCOUNT) == OK)
2002 for (i = 0; i < GARGCOUNT; ++i)
2003 if (GARGLIST[i].ae_fname != NULL)
2005 AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname =
2006 vim_strsave(GARGLIST[i].ae_fname);
2007 AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
2008 GARGLIST[i].ae_fnum;
2009 ++gap->ga_len;
2012 #endif
2016 * ":previous", ":sprevious", ":Next" and ":sNext".
2018 void
2019 ex_previous(eap)
2020 exarg_T *eap;
2022 /* If past the last one already, go to the last one. */
2023 if (curwin->w_arg_idx - (int)eap->line2 >= ARGCOUNT)
2024 do_argfile(eap, ARGCOUNT - 1);
2025 else
2026 do_argfile(eap, curwin->w_arg_idx - (int)eap->line2);
2030 * ":rewind", ":first", ":sfirst" and ":srewind".
2032 void
2033 ex_rewind(eap)
2034 exarg_T *eap;
2036 do_argfile(eap, 0);
2040 * ":last" and ":slast".
2042 void
2043 ex_last(eap)
2044 exarg_T *eap;
2046 do_argfile(eap, ARGCOUNT - 1);
2050 * ":argument" and ":sargument".
2052 void
2053 ex_argument(eap)
2054 exarg_T *eap;
2056 int i;
2058 if (eap->addr_count > 0)
2059 i = eap->line2 - 1;
2060 else
2061 i = curwin->w_arg_idx;
2062 do_argfile(eap, i);
2066 * Edit file "argn" of the argument lists.
2068 void
2069 do_argfile(eap, argn)
2070 exarg_T *eap;
2071 int argn;
2073 int other;
2074 char_u *p;
2075 int old_arg_idx = curwin->w_arg_idx;
2077 if (argn < 0 || argn >= ARGCOUNT)
2079 if (ARGCOUNT <= 1)
2080 EMSG(_("E163: There is only one file to edit"));
2081 else if (argn < 0)
2082 EMSG(_("E164: Cannot go before first file"));
2083 else
2084 EMSG(_("E165: Cannot go beyond last file"));
2086 else
2088 setpcmark();
2089 #ifdef FEAT_GUI
2090 need_mouse_correct = TRUE;
2091 #endif
2093 #ifdef FEAT_WINDOWS
2094 /* split window or create new tab page first */
2095 if (*eap->cmd == 's' || cmdmod.tab != 0)
2097 if (win_split(0, 0) == FAIL)
2098 return;
2099 # ifdef FEAT_SCROLLBIND
2100 curwin->w_p_scb = FALSE;
2101 # endif
2103 else
2104 #endif
2107 * if 'hidden' set, only check for changed file when re-editing
2108 * the same buffer
2110 other = TRUE;
2111 if (P_HID(curbuf))
2113 p = fix_fname(alist_name(&ARGLIST[argn]));
2114 other = otherfile(p);
2115 vim_free(p);
2117 if ((!P_HID(curbuf) || !other)
2118 && check_changed(curbuf, TRUE, !other, eap->forceit, FALSE))
2119 return;
2122 curwin->w_arg_idx = argn;
2123 if (argn == ARGCOUNT - 1
2124 #ifdef FEAT_WINDOWS
2125 && curwin->w_alist == &global_alist
2126 #endif
2128 arg_had_last = TRUE;
2130 /* Edit the file; always use the last known line number.
2131 * When it fails (e.g. Abort for already edited file) restore the
2132 * argument index. */
2133 if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
2134 eap, ECMD_LAST,
2135 (P_HID(curwin->w_buffer) ? ECMD_HIDE : 0)
2136 + (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
2137 curwin->w_arg_idx = old_arg_idx;
2138 /* like Vi: set the mark where the cursor is in the file. */
2139 else if (eap->cmdidx != CMD_argdo)
2140 setmark('\'');
2145 * ":next", and commands that behave like it.
2147 void
2148 ex_next(eap)
2149 exarg_T *eap;
2151 int i;
2154 * check for changed buffer now, if this fails the argument list is not
2155 * redefined.
2157 if ( P_HID(curbuf)
2158 || eap->cmdidx == CMD_snext
2159 || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE))
2161 if (*eap->arg != NUL) /* redefine file list */
2163 if (do_arglist(eap->arg, AL_SET, 0) == FAIL)
2164 return;
2165 i = 0;
2167 else
2168 i = curwin->w_arg_idx + (int)eap->line2;
2169 do_argfile(eap, i);
2173 #ifdef FEAT_LISTCMDS
2175 * ":argedit"
2177 void
2178 ex_argedit(eap)
2179 exarg_T *eap;
2181 int fnum;
2182 int i;
2183 char_u *s;
2185 /* Add the argument to the buffer list and get the buffer number. */
2186 fnum = buflist_add(eap->arg, BLN_LISTED);
2188 /* Check if this argument is already in the argument list. */
2189 for (i = 0; i < ARGCOUNT; ++i)
2190 if (ARGLIST[i].ae_fnum == fnum)
2191 break;
2192 if (i == ARGCOUNT)
2194 /* Can't find it, add it to the argument list. */
2195 s = vim_strsave(eap->arg);
2196 if (s == NULL)
2197 return;
2198 i = alist_add_list(1, &s,
2199 eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
2200 if (i < 0)
2201 return;
2202 curwin->w_arg_idx = i;
2205 alist_check_arg_idx();
2207 /* Edit the argument. */
2208 do_argfile(eap, i);
2212 * ":argadd"
2214 void
2215 ex_argadd(eap)
2216 exarg_T *eap;
2218 do_arglist(eap->arg, AL_ADD,
2219 eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
2220 #ifdef FEAT_TITLE
2221 maketitle();
2222 #endif
2226 * ":argdelete"
2228 void
2229 ex_argdelete(eap)
2230 exarg_T *eap;
2232 int i;
2233 int n;
2235 if (eap->addr_count > 0)
2237 /* ":1,4argdel": Delete all arguments in the range. */
2238 if (eap->line2 > ARGCOUNT)
2239 eap->line2 = ARGCOUNT;
2240 n = eap->line2 - eap->line1 + 1;
2241 if (*eap->arg != NUL || n <= 0)
2242 EMSG(_(e_invarg));
2243 else
2245 for (i = eap->line1; i <= eap->line2; ++i)
2246 vim_free(ARGLIST[i - 1].ae_fname);
2247 mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2,
2248 (size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T)));
2249 ALIST(curwin)->al_ga.ga_len -= n;
2250 if (curwin->w_arg_idx >= eap->line2)
2251 curwin->w_arg_idx -= n;
2252 else if (curwin->w_arg_idx > eap->line1)
2253 curwin->w_arg_idx = eap->line1;
2256 else if (*eap->arg == NUL)
2257 EMSG(_(e_argreq));
2258 else
2259 do_arglist(eap->arg, AL_DEL, 0);
2260 #ifdef FEAT_TITLE
2261 maketitle();
2262 #endif
2266 * ":argdo", ":windo", ":bufdo", ":tabdo"
2268 void
2269 ex_listdo(eap)
2270 exarg_T *eap;
2272 int i;
2273 #ifdef FEAT_WINDOWS
2274 win_T *wp;
2275 tabpage_T *tp;
2276 #endif
2277 buf_T *buf;
2278 int next_fnum = 0;
2279 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2280 char_u *save_ei = NULL;
2281 #endif
2282 char_u *p_shm_save;
2284 #ifndef FEAT_WINDOWS
2285 if (eap->cmdidx == CMD_windo)
2287 ex_ni(eap);
2288 return;
2290 #endif
2292 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2293 if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo)
2294 /* Don't do syntax HL autocommands. Skipping the syntax file is a
2295 * great speed improvement. */
2296 save_ei = au_event_disable(",Syntax");
2297 #endif
2299 if (eap->cmdidx == CMD_windo
2300 || eap->cmdidx == CMD_tabdo
2301 || P_HID(curbuf)
2302 || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE))
2304 /* start at the first argument/window/buffer */
2305 i = 0;
2306 #ifdef FEAT_WINDOWS
2307 wp = firstwin;
2308 tp = first_tabpage;
2309 #endif
2310 /* set pcmark now */
2311 if (eap->cmdidx == CMD_bufdo)
2312 goto_buffer(eap, DOBUF_FIRST, FORWARD, 0);
2313 else
2314 setpcmark();
2315 listcmd_busy = TRUE; /* avoids setting pcmark below */
2317 while (!got_int)
2319 if (eap->cmdidx == CMD_argdo)
2321 /* go to argument "i" */
2322 if (i == ARGCOUNT)
2323 break;
2324 /* Don't call do_argfile() when already there, it will try
2325 * reloading the file. */
2326 if (curwin->w_arg_idx != i || !editing_arg_idx(curwin))
2328 /* Clear 'shm' to avoid that the file message overwrites
2329 * any output from the command. */
2330 p_shm_save = vim_strsave(p_shm);
2331 set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
2332 do_argfile(eap, i);
2333 set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
2334 vim_free(p_shm_save);
2336 if (curwin->w_arg_idx != i)
2337 break;
2338 ++i;
2340 #ifdef FEAT_WINDOWS
2341 else if (eap->cmdidx == CMD_windo)
2343 /* go to window "wp" */
2344 if (!win_valid(wp))
2345 break;
2346 win_goto(wp);
2347 if (curwin != wp)
2348 break; /* something must be wrong */
2349 wp = curwin->w_next;
2351 else if (eap->cmdidx == CMD_tabdo)
2353 /* go to window "tp" */
2354 if (!valid_tabpage(tp))
2355 break;
2356 goto_tabpage_tp(tp);
2357 tp = tp->tp_next;
2359 #endif
2360 else if (eap->cmdidx == CMD_bufdo)
2362 /* Remember the number of the next listed buffer, in case
2363 * ":bwipe" is used or autocommands do something strange. */
2364 next_fnum = -1;
2365 for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
2366 if (buf->b_p_bl)
2368 next_fnum = buf->b_fnum;
2369 break;
2373 /* execute the command */
2374 do_cmdline(eap->arg, eap->getline, eap->cookie,
2375 DOCMD_VERBOSE + DOCMD_NOWAIT);
2377 if (eap->cmdidx == CMD_bufdo)
2379 /* Done? */
2380 if (next_fnum < 0)
2381 break;
2382 /* Check if the buffer still exists. */
2383 for (buf = firstbuf; buf != NULL; buf = buf->b_next)
2384 if (buf->b_fnum == next_fnum)
2385 break;
2386 if (buf == NULL)
2387 break;
2389 /* Go to the next buffer. Clear 'shm' to avoid that the file
2390 * message overwrites any output from the command. */
2391 p_shm_save = vim_strsave(p_shm);
2392 set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
2393 goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
2394 set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
2395 vim_free(p_shm_save);
2397 /* If autocommands took us elsewhere, quit here */
2398 if (curbuf->b_fnum != next_fnum)
2399 break;
2402 if (eap->cmdidx == CMD_windo)
2404 validate_cursor(); /* cursor may have moved */
2405 #ifdef FEAT_SCROLLBIND
2406 /* required when 'scrollbind' has been set */
2407 if (curwin->w_p_scb)
2408 do_check_scrollbind(TRUE);
2409 #endif
2412 listcmd_busy = FALSE;
2415 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
2416 if (save_ei != NULL)
2418 au_event_restore(save_ei);
2419 apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
2420 curbuf->b_fname, TRUE, curbuf);
2422 #endif
2426 * Add files[count] to the arglist of the current window after arg "after".
2427 * The file names in files[count] must have been allocated and are taken over.
2428 * Files[] itself is not taken over.
2429 * Returns index of first added argument. Returns -1 when failed (out of mem).
2431 static int
2432 alist_add_list(count, files, after)
2433 int count;
2434 char_u **files;
2435 int after; /* where to add: 0 = before first one */
2437 int i;
2439 if (ga_grow(&ALIST(curwin)->al_ga, count) == OK)
2441 if (after < 0)
2442 after = 0;
2443 if (after > ARGCOUNT)
2444 after = ARGCOUNT;
2445 if (after < ARGCOUNT)
2446 mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
2447 (ARGCOUNT - after) * sizeof(aentry_T));
2448 for (i = 0; i < count; ++i)
2450 ARGLIST[after + i].ae_fname = files[i];
2451 ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
2453 ALIST(curwin)->al_ga.ga_len += count;
2454 if (curwin->w_arg_idx >= after)
2455 ++curwin->w_arg_idx;
2456 return after;
2459 for (i = 0; i < count; ++i)
2460 vim_free(files[i]);
2461 return -1;
2464 #endif /* FEAT_LISTCMDS */
2466 #ifdef FEAT_EVAL
2468 * ":compiler[!] {name}"
2470 void
2471 ex_compiler(eap)
2472 exarg_T *eap;
2474 char_u *buf;
2475 char_u *old_cur_comp = NULL;
2476 char_u *p;
2478 if (*eap->arg == NUL)
2480 /* List all compiler scripts. */
2481 do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')");
2482 /* ) keep the indenter happy... */
2484 else
2486 buf = alloc((unsigned)(STRLEN(eap->arg) + 14));
2487 if (buf != NULL)
2489 if (eap->forceit)
2491 /* ":compiler! {name}" sets global options */
2492 do_cmdline_cmd((char_u *)
2493 "command -nargs=* CompilerSet set <args>");
2495 else
2497 /* ":compiler! {name}" sets local options.
2498 * To remain backwards compatible "current_compiler" is always
2499 * used. A user's compiler plugin may set it, the distributed
2500 * plugin will then skip the settings. Afterwards set
2501 * "b:current_compiler" and restore "current_compiler". */
2502 old_cur_comp = get_var_value((char_u *)"current_compiler");
2503 if (old_cur_comp != NULL)
2504 old_cur_comp = vim_strsave(old_cur_comp);
2505 do_cmdline_cmd((char_u *)
2506 "command -nargs=* CompilerSet setlocal <args>");
2508 do_unlet((char_u *)"current_compiler", TRUE);
2509 do_unlet((char_u *)"b:current_compiler", TRUE);
2511 sprintf((char *)buf, "compiler/%s.vim", eap->arg);
2512 if (source_runtime(buf, TRUE) == FAIL)
2513 EMSG2(_("E666: compiler not supported: %s"), eap->arg);
2514 vim_free(buf);
2516 do_cmdline_cmd((char_u *)":delcommand CompilerSet");
2518 /* Set "b:current_compiler" from "current_compiler". */
2519 p = get_var_value((char_u *)"current_compiler");
2520 if (p != NULL)
2521 set_internal_string_var((char_u *)"b:current_compiler", p);
2523 /* Restore "current_compiler" for ":compiler {name}". */
2524 if (!eap->forceit)
2526 if (old_cur_comp != NULL)
2528 set_internal_string_var((char_u *)"current_compiler",
2529 old_cur_comp);
2530 vim_free(old_cur_comp);
2532 else
2533 do_unlet((char_u *)"current_compiler", TRUE);
2538 #endif
2541 * ":runtime {name}"
2543 void
2544 ex_runtime(eap)
2545 exarg_T *eap;
2547 source_runtime(eap->arg, eap->forceit);
2550 static void source_callback __ARGS((char_u *fname, void *cookie));
2552 static void
2553 source_callback(fname, cookie)
2554 char_u *fname;
2555 void *cookie UNUSED;
2557 (void)do_source(fname, FALSE, DOSO_NONE);
2561 * Source the file "name" from all directories in 'runtimepath'.
2562 * "name" can contain wildcards.
2563 * When "all" is TRUE, source all files, otherwise only the first one.
2564 * return FAIL when no file could be sourced, OK otherwise.
2567 source_runtime(name, all)
2568 char_u *name;
2569 int all;
2571 return do_in_runtimepath(name, all, source_callback, NULL);
2575 * Find "name" in 'runtimepath'. When found, invoke the callback function for
2576 * it: callback(fname, "cookie")
2577 * When "all" is TRUE repeat for all matches, otherwise only the first one is
2578 * used.
2579 * Returns OK when at least one match found, FAIL otherwise.
2582 do_in_runtimepath(name, all, callback, cookie)
2583 char_u *name;
2584 int all;
2585 void (*callback)__ARGS((char_u *fname, void *ck));
2586 void *cookie;
2588 char_u *rtp;
2589 char_u *np;
2590 char_u *buf;
2591 char_u *rtp_copy;
2592 char_u *tail;
2593 int num_files;
2594 char_u **files;
2595 int i;
2596 int did_one = FALSE;
2597 #ifdef AMIGA
2598 struct Process *proc = (struct Process *)FindTask(0L);
2599 APTR save_winptr = proc->pr_WindowPtr;
2601 /* Avoid a requester here for a volume that doesn't exist. */
2602 proc->pr_WindowPtr = (APTR)-1L;
2603 #endif
2605 /* Make a copy of 'runtimepath'. Invoking the callback may change the
2606 * value. */
2607 rtp_copy = vim_strsave(p_rtp);
2608 buf = alloc(MAXPATHL);
2609 if (buf != NULL && rtp_copy != NULL)
2611 if (p_verbose > 1)
2613 verbose_enter();
2614 smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
2615 (char *)name, (char *)p_rtp);
2616 verbose_leave();
2619 /* Loop over all entries in 'runtimepath'. */
2620 rtp = rtp_copy;
2621 while (*rtp != NUL && (all || !did_one))
2623 /* Copy the path from 'runtimepath' to buf[]. */
2624 copy_option_part(&rtp, buf, MAXPATHL, ",");
2625 if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL)
2627 add_pathsep(buf);
2628 tail = buf + STRLEN(buf);
2630 /* Loop over all patterns in "name" */
2631 np = name;
2632 while (*np != NUL && (all || !did_one))
2634 /* Append the pattern from "name" to buf[]. */
2635 copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)),
2636 "\t ");
2638 if (p_verbose > 2)
2640 verbose_enter();
2641 smsg((char_u *)_("Searching for \"%s\""), buf);
2642 verbose_leave();
2645 /* Expand wildcards, invoke the callback for each match. */
2646 if (gen_expand_wildcards(1, &buf, &num_files, &files,
2647 EW_FILE) == OK)
2649 for (i = 0; i < num_files; ++i)
2651 (*callback)(files[i], cookie);
2652 did_one = TRUE;
2653 if (!all)
2654 break;
2656 FreeWild(num_files, files);
2662 vim_free(buf);
2663 vim_free(rtp_copy);
2664 if (p_verbose > 0 && !did_one)
2666 verbose_enter();
2667 smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name);
2668 verbose_leave();
2671 #ifdef AMIGA
2672 proc->pr_WindowPtr = save_winptr;
2673 #endif
2675 return did_one ? OK : FAIL;
2678 #if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
2680 * ":options"
2682 void
2683 ex_options(eap)
2684 exarg_T *eap UNUSED;
2686 cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
2688 #endif
2691 * ":source {fname}"
2693 void
2694 ex_source(eap)
2695 exarg_T *eap;
2697 #ifdef FEAT_BROWSE
2698 if (cmdmod.browse)
2700 char_u *fname = NULL;
2702 fname = do_browse(0, (char_u *)_("Source Vim script"), eap->arg,
2703 NULL, NULL, BROWSE_FILTER_MACROS, NULL);
2704 if (fname != NULL)
2706 cmd_source(fname, eap);
2707 vim_free(fname);
2710 else
2711 #endif
2712 cmd_source(eap->arg, eap);
2715 static void
2716 cmd_source(fname, eap)
2717 char_u *fname;
2718 exarg_T *eap;
2720 if (*fname == NUL)
2721 EMSG(_(e_argreq));
2723 else if (eap != NULL && eap->forceit)
2724 /* ":source!": read Normal mdoe commands
2725 * Need to execute the commands directly. This is required at least
2726 * for:
2727 * - ":g" command busy
2728 * - after ":argdo", ":windo" or ":bufdo"
2729 * - another command follows
2730 * - inside a loop
2732 openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL
2733 #ifdef FEAT_EVAL
2734 || eap->cstack->cs_idx >= 0
2735 #endif
2738 /* ":source" read ex commands */
2739 else if (do_source(fname, FALSE, DOSO_NONE) == FAIL)
2740 EMSG2(_(e_notopen), fname);
2744 * ":source" and associated commands.
2747 * Structure used to store info for each sourced file.
2748 * It is shared between do_source() and getsourceline().
2749 * This is required, because it needs to be handed to do_cmdline() and
2750 * sourcing can be done recursively.
2752 struct source_cookie
2754 FILE *fp; /* opened file for sourcing */
2755 char_u *nextline; /* if not NULL: line that was read ahead */
2756 int finished; /* ":finish" used */
2757 #if defined (USE_CRNL) || defined (USE_CR)
2758 int fileformat; /* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
2759 int error; /* TRUE if LF found after CR-LF */
2760 #endif
2761 #ifdef FEAT_EVAL
2762 linenr_T breakpoint; /* next line with breakpoint or zero */
2763 char_u *fname; /* name of sourced file */
2764 int dbg_tick; /* debug_tick when breakpoint was set */
2765 int level; /* top nesting level of sourced file */
2766 #endif
2767 #ifdef FEAT_MBYTE
2768 vimconv_T conv; /* type of conversion */
2769 #endif
2772 #ifdef FEAT_EVAL
2774 * Return the address holding the next breakpoint line for a source cookie.
2776 linenr_T *
2777 source_breakpoint(cookie)
2778 void *cookie;
2780 return &((struct source_cookie *)cookie)->breakpoint;
2784 * Return the address holding the debug tick for a source cookie.
2786 int *
2787 source_dbg_tick(cookie)
2788 void *cookie;
2790 return &((struct source_cookie *)cookie)->dbg_tick;
2794 * Return the nesting level for a source cookie.
2797 source_level(cookie)
2798 void *cookie;
2800 return ((struct source_cookie *)cookie)->level;
2802 #endif
2804 static char_u *get_one_sourceline __ARGS((struct source_cookie *sp));
2806 #if defined(WIN32) && defined(FEAT_CSCOPE)
2807 static FILE *fopen_noinh_readbin __ARGS((char *filename));
2810 * Special function to open a file without handle inheritance.
2812 static FILE *
2813 fopen_noinh_readbin(filename)
2814 char *filename;
2816 int fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0);
2818 if (fd_tmp == -1)
2819 return NULL;
2820 return fdopen(fd_tmp, READBIN);
2822 #endif
2826 * do_source: Read the file "fname" and execute its lines as EX commands.
2828 * This function may be called recursively!
2830 * return FAIL if file could not be opened, OK otherwise
2833 do_source(fname, check_other, is_vimrc)
2834 char_u *fname;
2835 int check_other; /* check for .vimrc and _vimrc */
2836 int is_vimrc; /* DOSO_ value */
2838 struct source_cookie cookie;
2839 char_u *save_sourcing_name;
2840 linenr_T save_sourcing_lnum;
2841 char_u *p;
2842 char_u *fname_exp;
2843 char_u *firstline = NULL;
2844 int retval = FAIL;
2845 #ifdef FEAT_EVAL
2846 scid_T save_current_SID;
2847 static scid_T last_current_SID = 0;
2848 void *save_funccalp;
2849 int save_debug_break_level = debug_break_level;
2850 scriptitem_T *si = NULL;
2851 # ifdef UNIX
2852 struct stat st;
2853 int stat_ok;
2854 # endif
2855 #endif
2856 #ifdef STARTUPTIME
2857 struct timeval tv_rel;
2858 struct timeval tv_start;
2859 #endif
2860 #ifdef FEAT_PROFILE
2861 proftime_T wait_start;
2862 #endif
2864 #ifdef RISCOS
2865 p = mch_munge_fname(fname);
2866 #else
2867 p = expand_env_save(fname);
2868 #endif
2869 if (p == NULL)
2870 return retval;
2871 fname_exp = fix_fname(p);
2872 vim_free(p);
2873 if (fname_exp == NULL)
2874 return retval;
2875 if (mch_isdir(fname_exp))
2877 smsg((char_u *)_("Cannot source a directory: \"%s\""), fname);
2878 goto theend;
2881 #ifdef FEAT_AUTOCMD
2882 /* Apply SourceCmd autocommands, they should get the file and source it. */
2883 if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
2884 && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
2885 FALSE, curbuf))
2887 # ifdef FEAT_EVAL
2888 retval = aborting() ? FAIL : OK;
2889 # else
2890 retval = OK;
2891 # endif
2892 goto theend;
2895 /* Apply SourcePre autocommands, they may get the file. */
2896 apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
2897 #endif
2899 #if defined(WIN32) && defined(FEAT_CSCOPE)
2900 cookie.fp = fopen_noinh_readbin((char *)fname_exp);
2901 #else
2902 cookie.fp = mch_fopen((char *)fname_exp, READBIN);
2903 #endif
2904 if (cookie.fp == NULL && check_other)
2907 * Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
2908 * and ".exrc" by "_exrc" or vice versa.
2910 p = gettail(fname_exp);
2911 if ((*p == '.' || *p == '_')
2912 && (STRICMP(p + 1, "vimrc") == 0
2913 || STRICMP(p + 1, "gvimrc") == 0
2914 || STRICMP(p + 1, "exrc") == 0))
2916 if (*p == '_')
2917 *p = '.';
2918 else
2919 *p = '_';
2920 #if defined(WIN32) && defined(FEAT_CSCOPE)
2921 cookie.fp = fopen_noinh_readbin((char *)fname_exp);
2922 #else
2923 cookie.fp = mch_fopen((char *)fname_exp, READBIN);
2924 #endif
2928 if (cookie.fp == NULL)
2930 if (p_verbose > 0)
2932 verbose_enter();
2933 if (sourcing_name == NULL)
2934 smsg((char_u *)_("could not source \"%s\""), fname);
2935 else
2936 smsg((char_u *)_("line %ld: could not source \"%s\""),
2937 sourcing_lnum, fname);
2938 verbose_leave();
2940 goto theend;
2944 * The file exists.
2945 * - In verbose mode, give a message.
2946 * - For a vimrc file, may want to set 'compatible', call vimrc_found().
2948 if (p_verbose > 1)
2950 verbose_enter();
2951 if (sourcing_name == NULL)
2952 smsg((char_u *)_("sourcing \"%s\""), fname);
2953 else
2954 smsg((char_u *)_("line %ld: sourcing \"%s\""),
2955 sourcing_lnum, fname);
2956 verbose_leave();
2958 if (is_vimrc == DOSO_VIMRC)
2959 vimrc_found(fname_exp, (char_u *)"MYVIMRC");
2960 else if (is_vimrc == DOSO_GVIMRC)
2961 vimrc_found(fname_exp, (char_u *)"MYGVIMRC");
2963 #ifdef USE_CRNL
2964 /* If no automatic file format: Set default to CR-NL. */
2965 if (*p_ffs == NUL)
2966 cookie.fileformat = EOL_DOS;
2967 else
2968 cookie.fileformat = EOL_UNKNOWN;
2969 cookie.error = FALSE;
2970 #endif
2972 #ifdef USE_CR
2973 /* If no automatic file format: Set default to CR. */
2974 if (*p_ffs == NUL)
2975 cookie.fileformat = EOL_MAC;
2976 else
2977 cookie.fileformat = EOL_UNKNOWN;
2978 cookie.error = FALSE;
2979 #endif
2981 cookie.nextline = NULL;
2982 cookie.finished = FALSE;
2984 #ifdef FEAT_EVAL
2986 * Check if this script has a breakpoint.
2988 cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
2989 cookie.fname = fname_exp;
2990 cookie.dbg_tick = debug_tick;
2992 cookie.level = ex_nesting_level;
2993 #endif
2996 * Keep the sourcing name/lnum, for recursive calls.
2998 save_sourcing_name = sourcing_name;
2999 sourcing_name = fname_exp;
3000 save_sourcing_lnum = sourcing_lnum;
3001 sourcing_lnum = 0;
3003 #ifdef FEAT_MBYTE
3004 cookie.conv.vc_type = CONV_NONE; /* no conversion */
3006 /* Read the first line so we can check for a UTF-8 BOM. */
3007 firstline = getsourceline(0, (void *)&cookie, 0);
3008 if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
3009 && firstline[1] == 0xbb && firstline[2] == 0xbf)
3011 /* Found BOM; setup conversion, skip over BOM and recode the line. */
3012 convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
3013 p = string_convert(&cookie.conv, firstline + 3, NULL);
3014 if (p == NULL)
3015 p = vim_strsave(firstline + 3);
3016 if (p != NULL)
3018 vim_free(firstline);
3019 firstline = p;
3022 #endif
3024 #ifdef STARTUPTIME
3025 time_push(&tv_rel, &tv_start);
3026 #endif
3028 #ifdef FEAT_EVAL
3029 # ifdef FEAT_PROFILE
3030 if (do_profiling == PROF_YES)
3031 prof_child_enter(&wait_start); /* entering a child now */
3032 # endif
3034 /* Don't use local function variables, if called from a function.
3035 * Also starts profiling timer for nested script. */
3036 save_funccalp = save_funccal();
3039 * Check if this script was sourced before to finds its SID.
3040 * If it's new, generate a new SID.
3042 save_current_SID = current_SID;
3043 # ifdef UNIX
3044 stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
3045 # endif
3046 for (current_SID = script_items.ga_len; current_SID > 0; --current_SID)
3048 si = &SCRIPT_ITEM(current_SID);
3049 if (si->sn_name != NULL
3050 && (
3051 # ifdef UNIX
3052 /* Compare dev/ino when possible, it catches symbolic
3053 * links. Also compare file names, the inode may change
3054 * when the file was edited. */
3055 ((stat_ok && si->sn_dev_valid)
3056 && (si->sn_dev == st.st_dev
3057 && si->sn_ino == st.st_ino)) ||
3058 # endif
3059 fnamecmp(si->sn_name, fname_exp) == 0))
3060 break;
3062 if (current_SID == 0)
3064 current_SID = ++last_current_SID;
3065 if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len))
3066 == FAIL)
3067 goto almosttheend;
3068 while (script_items.ga_len < current_SID)
3070 ++script_items.ga_len;
3071 SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
3072 # ifdef FEAT_PROFILE
3073 SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
3074 # endif
3076 si = &SCRIPT_ITEM(current_SID);
3077 si->sn_name = fname_exp;
3078 fname_exp = NULL;
3079 # ifdef UNIX
3080 if (stat_ok)
3082 si->sn_dev_valid = TRUE;
3083 si->sn_dev = st.st_dev;
3084 si->sn_ino = st.st_ino;
3086 else
3087 si->sn_dev_valid = FALSE;
3088 # endif
3090 /* Allocate the local script variables to use for this script. */
3091 new_script_vars(current_SID);
3094 # ifdef FEAT_PROFILE
3095 if (do_profiling == PROF_YES)
3097 int forceit;
3099 /* Check if we do profiling for this script. */
3100 if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit))
3102 script_do_profile(si);
3103 si->sn_pr_force = forceit;
3105 if (si->sn_prof_on)
3107 ++si->sn_pr_count;
3108 profile_start(&si->sn_pr_start);
3109 profile_zero(&si->sn_pr_children);
3112 # endif
3113 #endif
3116 * Call do_cmdline, which will call getsourceline() to get the lines.
3118 do_cmdline(firstline, getsourceline, (void *)&cookie,
3119 DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
3120 retval = OK;
3122 #ifdef FEAT_PROFILE
3123 if (do_profiling == PROF_YES)
3125 /* Get "si" again, "script_items" may have been reallocated. */
3126 si = &SCRIPT_ITEM(current_SID);
3127 if (si->sn_prof_on)
3129 profile_end(&si->sn_pr_start);
3130 profile_sub_wait(&wait_start, &si->sn_pr_start);
3131 profile_add(&si->sn_pr_total, &si->sn_pr_start);
3132 profile_self(&si->sn_pr_self, &si->sn_pr_start,
3133 &si->sn_pr_children);
3136 #endif
3138 if (got_int)
3139 EMSG(_(e_interr));
3140 sourcing_name = save_sourcing_name;
3141 sourcing_lnum = save_sourcing_lnum;
3142 if (p_verbose > 1)
3144 verbose_enter();
3145 smsg((char_u *)_("finished sourcing %s"), fname);
3146 if (sourcing_name != NULL)
3147 smsg((char_u *)_("continuing in %s"), sourcing_name);
3148 verbose_leave();
3150 #ifdef STARTUPTIME
3151 vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
3152 time_msg((char *)IObuff, &tv_start);
3153 time_pop(&tv_rel);
3154 #endif
3156 #ifdef FEAT_EVAL
3158 * After a "finish" in debug mode, need to break at first command of next
3159 * sourced file.
3161 if (save_debug_break_level > ex_nesting_level
3162 && debug_break_level == ex_nesting_level)
3163 ++debug_break_level;
3164 #endif
3166 #ifdef FEAT_EVAL
3167 almosttheend:
3168 current_SID = save_current_SID;
3169 restore_funccal(save_funccalp);
3170 # ifdef FEAT_PROFILE
3171 if (do_profiling == PROF_YES)
3172 prof_child_exit(&wait_start); /* leaving a child now */
3173 # endif
3174 #endif
3175 fclose(cookie.fp);
3176 vim_free(cookie.nextline);
3177 vim_free(firstline);
3178 #ifdef FEAT_MBYTE
3179 convert_setup(&cookie.conv, NULL, NULL);
3180 #endif
3182 theend:
3183 vim_free(fname_exp);
3184 return retval;
3187 #if defined(FEAT_EVAL) || defined(PROTO)
3190 * ":scriptnames"
3192 void
3193 ex_scriptnames(eap)
3194 exarg_T *eap UNUSED;
3196 int i;
3198 for (i = 1; i <= script_items.ga_len && !got_int; ++i)
3199 if (SCRIPT_ITEM(i).sn_name != NULL)
3200 smsg((char_u *)"%3d: %s", i, SCRIPT_ITEM(i).sn_name);
3203 # if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
3205 * Fix slashes in the list of script names for 'shellslash'.
3207 void
3208 scriptnames_slash_adjust()
3210 int i;
3212 for (i = 1; i <= script_items.ga_len; ++i)
3213 if (SCRIPT_ITEM(i).sn_name != NULL)
3214 slash_adjust(SCRIPT_ITEM(i).sn_name);
3216 # endif
3219 * Get a pointer to a script name. Used for ":verbose set".
3221 char_u *
3222 get_scriptname(id)
3223 scid_T id;
3225 if (id == SID_MODELINE)
3226 return (char_u *)_("modeline");
3227 if (id == SID_CMDARG)
3228 return (char_u *)_("--cmd argument");
3229 if (id == SID_CARG)
3230 return (char_u *)_("-c argument");
3231 if (id == SID_ENV)
3232 return (char_u *)_("environment variable");
3233 if (id == SID_ERROR)
3234 return (char_u *)_("error handler");
3235 return SCRIPT_ITEM(id).sn_name;
3238 # if defined(EXITFREE) || defined(PROTO)
3239 void
3240 free_scriptnames()
3242 int i;
3244 for (i = script_items.ga_len; i > 0; --i)
3245 vim_free(SCRIPT_ITEM(i).sn_name);
3246 ga_clear(&script_items);
3248 # endif
3250 #endif
3252 #if defined(USE_CR) || defined(PROTO)
3254 # if defined(__MSL__) && (__MSL__ >= 22)
3256 * Newer version of the Metrowerks library handle DOS and UNIX files
3257 * without help.
3258 * Test with earlier versions, MSL 2.2 is the library supplied with
3259 * Codewarrior Pro 2.
3261 char *
3262 fgets_cr(s, n, stream)
3263 char *s;
3264 int n;
3265 FILE *stream;
3267 return fgets(s, n, stream);
3269 # else
3271 * Version of fgets() which also works for lines ending in a <CR> only
3272 * (Macintosh format).
3273 * For older versions of the Metrowerks library.
3274 * At least CodeWarrior 9 needed this code.
3276 char *
3277 fgets_cr(s, n, stream)
3278 char *s;
3279 int n;
3280 FILE *stream;
3282 int c = 0;
3283 int char_read = 0;
3285 while (!feof(stream) && c != '\r' && c != '\n' && char_read < n - 1)
3287 c = fgetc(stream);
3288 s[char_read++] = c;
3289 /* If the file is in DOS format, we need to skip a NL after a CR. I
3290 * thought it was the other way around, but this appears to work... */
3291 if (c == '\n')
3293 c = fgetc(stream);
3294 if (c != '\r')
3295 ungetc(c, stream);
3299 s[char_read] = 0;
3300 if (char_read == 0)
3301 return NULL;
3303 if (feof(stream) && char_read == 1)
3304 return NULL;
3306 return s;
3308 # endif
3309 #endif
3312 * Get one full line from a sourced file.
3313 * Called by do_cmdline() when it's called from do_source().
3315 * Return a pointer to the line in allocated memory.
3316 * Return NULL for end-of-file or some error.
3318 char_u *
3319 getsourceline(c, cookie, indent)
3320 int c UNUSED;
3321 void *cookie;
3322 int indent UNUSED;
3324 struct source_cookie *sp = (struct source_cookie *)cookie;
3325 char_u *line;
3326 char_u *p, *s;
3328 #ifdef FEAT_EVAL
3329 /* If breakpoints have been added/deleted need to check for it. */
3330 if (sp->dbg_tick < debug_tick)
3332 sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
3333 sp->dbg_tick = debug_tick;
3335 # ifdef FEAT_PROFILE
3336 if (do_profiling == PROF_YES)
3337 script_line_end();
3338 # endif
3339 #endif
3341 * Get current line. If there is a read-ahead line, use it, otherwise get
3342 * one now.
3344 if (sp->finished)
3345 line = NULL;
3346 else if (sp->nextline == NULL)
3347 line = get_one_sourceline(sp);
3348 else
3350 line = sp->nextline;
3351 sp->nextline = NULL;
3352 ++sourcing_lnum;
3354 #ifdef FEAT_PROFILE
3355 if (line != NULL && do_profiling == PROF_YES)
3356 script_line_start();
3357 #endif
3359 /* Only concatenate lines starting with a \ when 'cpoptions' doesn't
3360 * contain the 'C' flag. */
3361 if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL))
3363 /* compensate for the one line read-ahead */
3364 --sourcing_lnum;
3365 for (;;)
3367 sp->nextline = get_one_sourceline(sp);
3368 if (sp->nextline == NULL)
3369 break;
3370 p = skipwhite(sp->nextline);
3371 if (*p != '\\')
3372 break;
3373 s = alloc((unsigned)(STRLEN(line) + STRLEN(p)));
3374 if (s == NULL) /* out of memory */
3375 break;
3376 STRCPY(s, line);
3377 STRCAT(s, p + 1);
3378 vim_free(line);
3379 line = s;
3380 vim_free(sp->nextline);
3384 #ifdef FEAT_MBYTE
3385 if (line != NULL && sp->conv.vc_type != CONV_NONE)
3387 /* Convert the encoding of the script line. */
3388 s = string_convert(&sp->conv, line, NULL);
3389 if (s != NULL)
3391 vim_free(line);
3392 line = s;
3395 #endif
3397 #ifdef FEAT_EVAL
3398 /* Did we encounter a breakpoint? */
3399 if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
3401 dbg_breakpoint(sp->fname, sourcing_lnum);
3402 /* Find next breakpoint. */
3403 sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
3404 sp->dbg_tick = debug_tick;
3406 #endif
3408 return line;
3411 static char_u *
3412 get_one_sourceline(sp)
3413 struct source_cookie *sp;
3415 garray_T ga;
3416 int len;
3417 int c;
3418 char_u *buf;
3419 #ifdef USE_CRNL
3420 int has_cr; /* CR-LF found */
3421 #endif
3422 #ifdef USE_CR
3423 char_u *scan;
3424 #endif
3425 int have_read = FALSE;
3427 /* use a growarray to store the sourced line */
3428 ga_init2(&ga, 1, 250);
3431 * Loop until there is a finished line (or end-of-file).
3433 sourcing_lnum++;
3434 for (;;)
3436 /* make room to read at least 120 (more) characters */
3437 if (ga_grow(&ga, 120) == FAIL)
3438 break;
3439 buf = (char_u *)ga.ga_data;
3441 #ifdef USE_CR
3442 if (sp->fileformat == EOL_MAC)
3444 if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
3445 sp->fp) == NULL)
3446 break;
3448 else
3449 #endif
3450 if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
3451 sp->fp) == NULL)
3452 break;
3453 len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
3454 #ifdef USE_CRNL
3455 /* Ignore a trailing CTRL-Z, when in Dos mode. Only recognize the
3456 * CTRL-Z by its own, or after a NL. */
3457 if ( (len == 1 || (len >= 2 && buf[len - 2] == '\n'))
3458 && sp->fileformat == EOL_DOS
3459 && buf[len - 1] == Ctrl_Z)
3461 buf[len - 1] = NUL;
3462 break;
3464 #endif
3466 #ifdef USE_CR
3467 /* If the read doesn't stop on a new line, and there's
3468 * some CR then we assume a Mac format */
3469 if (sp->fileformat == EOL_UNKNOWN)
3471 if (buf[len - 1] != '\n' && vim_strchr(buf, '\r') != NULL)
3472 sp->fileformat = EOL_MAC;
3473 else
3474 sp->fileformat = EOL_UNIX;
3477 if (sp->fileformat == EOL_MAC)
3479 scan = vim_strchr(buf, '\r');
3481 if (scan != NULL)
3483 *scan = '\n';
3484 if (*(scan + 1) != 0)
3486 *(scan + 1) = 0;
3487 fseek(sp->fp, (long)(scan - buf - len + 1), SEEK_CUR);
3490 len = STRLEN(buf);
3492 #endif
3494 have_read = TRUE;
3495 ga.ga_len = len;
3497 /* If the line was longer than the buffer, read more. */
3498 if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
3499 continue;
3501 if (len >= 1 && buf[len - 1] == '\n') /* remove trailing NL */
3503 #ifdef USE_CRNL
3504 has_cr = (len >= 2 && buf[len - 2] == '\r');
3505 if (sp->fileformat == EOL_UNKNOWN)
3507 if (has_cr)
3508 sp->fileformat = EOL_DOS;
3509 else
3510 sp->fileformat = EOL_UNIX;
3513 if (sp->fileformat == EOL_DOS)
3515 if (has_cr) /* replace trailing CR */
3517 buf[len - 2] = '\n';
3518 --len;
3519 --ga.ga_len;
3521 else /* lines like ":map xx yy^M" will have failed */
3523 if (!sp->error)
3525 msg_source(hl_attr(HLF_W));
3526 EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
3528 sp->error = TRUE;
3529 sp->fileformat = EOL_UNIX;
3532 #endif
3533 /* The '\n' is escaped if there is an odd number of ^V's just
3534 * before it, first set "c" just before the 'V's and then check
3535 * len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo */
3536 for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--)
3538 if ((len & 1) != (c & 1)) /* escaped NL, read more */
3540 sourcing_lnum++;
3541 continue;
3544 buf[len - 1] = NUL; /* remove the NL */
3548 * Check for ^C here now and then, so recursive :so can be broken.
3550 line_breakcheck();
3551 break;
3554 if (have_read)
3555 return (char_u *)ga.ga_data;
3557 vim_free(ga.ga_data);
3558 return NULL;
3561 #if defined(FEAT_PROFILE) || defined(PROTO)
3563 * Called when starting to read a script line.
3564 * "sourcing_lnum" must be correct!
3565 * When skipping lines it may not actually be executed, but we won't find out
3566 * until later and we need to store the time now.
3568 void
3569 script_line_start()
3571 scriptitem_T *si;
3572 sn_prl_T *pp;
3574 if (current_SID <= 0 || current_SID > script_items.ga_len)
3575 return;
3576 si = &SCRIPT_ITEM(current_SID);
3577 if (si->sn_prof_on && sourcing_lnum >= 1)
3579 /* Grow the array before starting the timer, so that the time spent
3580 * here isn't counted. */
3581 ga_grow(&si->sn_prl_ga, (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
3582 si->sn_prl_idx = sourcing_lnum - 1;
3583 while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
3584 && si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
3586 /* Zero counters for a line that was not used before. */
3587 pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len);
3588 pp->snp_count = 0;
3589 profile_zero(&pp->sn_prl_total);
3590 profile_zero(&pp->sn_prl_self);
3591 ++si->sn_prl_ga.ga_len;
3593 si->sn_prl_execed = FALSE;
3594 profile_start(&si->sn_prl_start);
3595 profile_zero(&si->sn_prl_children);
3596 profile_get_wait(&si->sn_prl_wait);
3601 * Called when actually executing a function line.
3603 void
3604 script_line_exec()
3606 scriptitem_T *si;
3608 if (current_SID <= 0 || current_SID > script_items.ga_len)
3609 return;
3610 si = &SCRIPT_ITEM(current_SID);
3611 if (si->sn_prof_on && si->sn_prl_idx >= 0)
3612 si->sn_prl_execed = TRUE;
3616 * Called when done with a function line.
3618 void
3619 script_line_end()
3621 scriptitem_T *si;
3622 sn_prl_T *pp;
3624 if (current_SID <= 0 || current_SID > script_items.ga_len)
3625 return;
3626 si = &SCRIPT_ITEM(current_SID);
3627 if (si->sn_prof_on && si->sn_prl_idx >= 0
3628 && si->sn_prl_idx < si->sn_prl_ga.ga_len)
3630 if (si->sn_prl_execed)
3632 pp = &PRL_ITEM(si, si->sn_prl_idx);
3633 ++pp->snp_count;
3634 profile_end(&si->sn_prl_start);
3635 profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start);
3636 profile_add(&pp->sn_prl_total, &si->sn_prl_start);
3637 profile_self(&pp->sn_prl_self, &si->sn_prl_start,
3638 &si->sn_prl_children);
3640 si->sn_prl_idx = -1;
3643 #endif
3646 * ":scriptencoding": Set encoding conversion for a sourced script.
3647 * Without the multi-byte feature it's simply ignored.
3649 void
3650 ex_scriptencoding(eap)
3651 exarg_T *eap UNUSED;
3653 #ifdef FEAT_MBYTE
3654 struct source_cookie *sp;
3655 char_u *name;
3657 if (!getline_equal(eap->getline, eap->cookie, getsourceline))
3659 EMSG(_("E167: :scriptencoding used outside of a sourced file"));
3660 return;
3663 if (*eap->arg != NUL)
3665 name = enc_canonize(eap->arg);
3666 if (name == NULL) /* out of memory */
3667 return;
3669 else
3670 name = eap->arg;
3672 /* Setup for conversion from the specified encoding to 'encoding'. */
3673 sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie);
3674 convert_setup(&sp->conv, name, p_enc);
3676 if (name != eap->arg)
3677 vim_free(name);
3678 #endif
3681 #if defined(FEAT_EVAL) || defined(PROTO)
3683 * ":finish": Mark a sourced file as finished.
3685 void
3686 ex_finish(eap)
3687 exarg_T *eap;
3689 if (getline_equal(eap->getline, eap->cookie, getsourceline))
3690 do_finish(eap, FALSE);
3691 else
3692 EMSG(_("E168: :finish used outside of a sourced file"));
3696 * Mark a sourced file as finished. Possibly makes the ":finish" pending.
3697 * Also called for a pending finish at the ":endtry" or after returning from
3698 * an extra do_cmdline(). "reanimate" is used in the latter case.
3700 void
3701 do_finish(eap, reanimate)
3702 exarg_T *eap;
3703 int reanimate;
3705 int idx;
3707 if (reanimate)
3708 ((struct source_cookie *)getline_cookie(eap->getline,
3709 eap->cookie))->finished = FALSE;
3712 * Cleanup (and inactivate) conditionals, but stop when a try conditional
3713 * not in its finally clause (which then is to be executed next) is found.
3714 * In this case, make the ":finish" pending for execution at the ":endtry".
3715 * Otherwise, finish normally.
3717 idx = cleanup_conditionals(eap->cstack, 0, TRUE);
3718 if (idx >= 0)
3720 eap->cstack->cs_pending[idx] = CSTP_FINISH;
3721 report_make_pending(CSTP_FINISH, NULL);
3723 else
3724 ((struct source_cookie *)getline_cookie(eap->getline,
3725 eap->cookie))->finished = TRUE;
3730 * Return TRUE when a sourced file had the ":finish" command: Don't give error
3731 * message for missing ":endif".
3732 * Return FALSE when not sourcing a file.
3735 source_finished(fgetline, cookie)
3736 char_u *(*fgetline) __ARGS((int, void *, int));
3737 void *cookie;
3739 return (getline_equal(fgetline, cookie, getsourceline)
3740 && ((struct source_cookie *)getline_cookie(
3741 fgetline, cookie))->finished);
3743 #endif
3745 #if defined(FEAT_LISTCMDS) || defined(PROTO)
3747 * ":checktime [buffer]"
3749 void
3750 ex_checktime(eap)
3751 exarg_T *eap;
3753 buf_T *buf;
3754 int save_no_check_timestamps = no_check_timestamps;
3756 no_check_timestamps = 0;
3757 if (eap->addr_count == 0) /* default is all buffers */
3758 check_timestamps(FALSE);
3759 else
3761 buf = buflist_findnr((int)eap->line2);
3762 if (buf != NULL) /* cannot happen? */
3763 (void)buf_check_timestamp(buf, FALSE);
3765 no_check_timestamps = save_no_check_timestamps;
3767 #endif
3769 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3770 && (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG))
3771 static char *get_locale_val __ARGS((int what));
3773 static char *
3774 get_locale_val(what)
3775 int what;
3777 char *loc;
3779 /* Obtain the locale value from the libraries. For DJGPP this is
3780 * redefined and it doesn't use the arguments. */
3781 loc = setlocale(what, NULL);
3783 # ifdef WIN32
3784 if (loc != NULL)
3786 char_u *p;
3788 /* setocale() returns something like "LC_COLLATE=<name>;LC_..." when
3789 * one of the values (e.g., LC_CTYPE) differs. */
3790 p = vim_strchr(loc, '=');
3791 if (p != NULL)
3793 loc = ++p;
3794 while (*p != NUL) /* remove trailing newline */
3796 if (*p < ' ' || *p == ';')
3798 *p = NUL;
3799 break;
3801 ++p;
3805 # endif
3807 return loc;
3809 #endif
3812 #ifdef WIN32
3814 * On MS-Windows locale names are strings like "German_Germany.1252", but
3815 * gettext expects "de". Try to translate one into another here for a few
3816 * supported languages.
3818 static char_u *
3819 gettext_lang(char_u *name)
3821 int i;
3822 static char *(mtable[]) = {
3823 "afrikaans", "af",
3824 "czech", "cs",
3825 "dutch", "nl",
3826 "german", "de",
3827 "english_united kingdom", "en_GB",
3828 "spanish", "es",
3829 "french", "fr",
3830 "italian", "it",
3831 "japanese", "ja",
3832 "korean", "ko",
3833 "norwegian", "no",
3834 "polish", "pl",
3835 "russian", "ru",
3836 "slovak", "sk",
3837 "swedish", "sv",
3838 "ukrainian", "uk",
3839 "chinese_china", "zh_CN",
3840 "chinese_taiwan", "zh_TW",
3841 NULL};
3843 for (i = 0; mtable[i] != NULL; i += 2)
3844 if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0)
3845 return mtable[i + 1];
3846 return name;
3848 #endif
3850 #if defined(FEAT_MULTI_LANG) || defined(PROTO)
3852 * Obtain the current messages language. Used to set the default for
3853 * 'helplang'. May return NULL or an empty string.
3855 char_u *
3856 get_mess_lang()
3858 char_u *p;
3860 # if (defined(HAVE_LOCALE_H) || defined(X_LOCALE))
3861 # if defined(LC_MESSAGES)
3862 p = (char_u *)get_locale_val(LC_MESSAGES);
3863 # else
3864 /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
3865 * may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME
3866 * and LC_MONETARY may be set differently for a Japanese working in the
3867 * US. */
3868 p = (char_u *)get_locale_val(LC_COLLATE);
3869 # endif
3870 # else
3871 p = mch_getenv((char_u *)"LC_ALL");
3872 if (p == NULL || *p == NUL)
3874 p = mch_getenv((char_u *)"LC_MESSAGES");
3875 if (p == NULL || *p == NUL)
3876 p = mch_getenv((char_u *)"LANG");
3878 # endif
3879 # ifdef WIN32
3880 p = gettext_lang(p);
3881 # endif
3882 return p;
3884 #endif
3886 /* Complicated #if; matches with where get_mess_env() is used below. */
3887 #if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3888 && defined(LC_MESSAGES))) \
3889 || ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3890 && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) \
3891 && !defined(LC_MESSAGES))
3892 static char_u *get_mess_env __ARGS((void));
3895 * Get the language used for messages from the environment.
3897 static char_u *
3898 get_mess_env()
3900 char_u *p;
3902 p = mch_getenv((char_u *)"LC_ALL");
3903 if (p == NULL || *p == NUL)
3905 p = mch_getenv((char_u *)"LC_MESSAGES");
3906 if (p == NULL || *p == NUL)
3908 p = mch_getenv((char_u *)"LANG");
3909 if (p != NULL && VIM_ISDIGIT(*p))
3910 p = NULL; /* ignore something like "1043" */
3911 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3912 if (p == NULL || *p == NUL)
3913 p = (char_u *)get_locale_val(LC_CTYPE);
3914 # endif
3917 return p;
3919 #endif
3921 #if defined(FEAT_EVAL) || defined(PROTO)
3924 * Set the "v:lang" variable according to the current locale setting.
3925 * Also do "v:lc_time"and "v:ctype".
3927 void
3928 set_lang_var()
3930 char_u *loc;
3932 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3933 loc = (char_u *)get_locale_val(LC_CTYPE);
3934 # else
3935 /* setlocale() not supported: use the default value */
3936 loc = (char_u *)"C";
3937 # endif
3938 set_vim_var_string(VV_CTYPE, loc, -1);
3940 /* When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
3941 * back to LC_CTYPE if it's empty. */
3942 # if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) && defined(LC_MESSAGES)
3943 loc = (char_u *)get_locale_val(LC_MESSAGES);
3944 # else
3945 loc = get_mess_env();
3946 # endif
3947 set_vim_var_string(VV_LANG, loc, -1);
3949 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3950 loc = (char_u *)get_locale_val(LC_TIME);
3951 # endif
3952 set_vim_var_string(VV_LC_TIME, loc, -1);
3954 #endif
3956 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3957 && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
3959 * ":language": Set the language (locale).
3961 void
3962 ex_language(eap)
3963 exarg_T *eap;
3965 char *loc;
3966 char_u *p;
3967 char_u *name;
3968 int what = LC_ALL;
3969 char *whatstr = "";
3970 #ifdef LC_MESSAGES
3971 # define VIM_LC_MESSAGES LC_MESSAGES
3972 #else
3973 # define VIM_LC_MESSAGES 6789
3974 #endif
3976 name = eap->arg;
3978 /* Check for "messages {name}", "ctype {name}" or "time {name}" argument.
3979 * Allow abbreviation, but require at least 3 characters to avoid
3980 * confusion with a two letter language name "me" or "ct". */
3981 p = skiptowhite(eap->arg);
3982 if ((*p == NUL || vim_iswhite(*p)) && p - eap->arg >= 3)
3984 if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0)
3986 what = VIM_LC_MESSAGES;
3987 name = skipwhite(p);
3988 whatstr = "messages ";
3990 else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0)
3992 what = LC_CTYPE;
3993 name = skipwhite(p);
3994 whatstr = "ctype ";
3996 else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0)
3998 what = LC_TIME;
3999 name = skipwhite(p);
4000 whatstr = "time ";
4004 if (*name == NUL)
4006 #ifndef LC_MESSAGES
4007 if (what == VIM_LC_MESSAGES)
4008 p = get_mess_env();
4009 else
4010 #endif
4011 p = (char_u *)setlocale(what, NULL);
4012 if (p == NULL || *p == NUL)
4013 p = (char_u *)"Unknown";
4014 smsg((char_u *)_("Current %slanguage: \"%s\""), whatstr, p);
4016 else
4018 #ifndef LC_MESSAGES
4019 if (what == VIM_LC_MESSAGES)
4020 loc = "";
4021 else
4022 #endif
4024 loc = setlocale(what, (char *)name);
4025 #if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
4026 /* Make sure strtod() uses a decimal point, not a comma. */
4027 setlocale(LC_NUMERIC, "C");
4028 #endif
4030 if (loc == NULL)
4031 EMSG2(_("E197: Cannot set language to \"%s\""), name);
4032 else
4034 #ifdef HAVE_NL_MSG_CAT_CNTR
4035 /* Need to do this for GNU gettext, otherwise cached translations
4036 * will be used again. */
4037 extern int _nl_msg_cat_cntr;
4039 ++_nl_msg_cat_cntr;
4040 #endif
4041 /* Reset $LC_ALL, otherwise it would overrule everything. */
4042 vim_setenv((char_u *)"LC_ALL", (char_u *)"");
4044 if (what != LC_TIME)
4046 /* Tell gettext() what to translate to. It apparently doesn't
4047 * use the currently effective locale. Also do this when
4048 * FEAT_GETTEXT isn't defined, so that shell commands use this
4049 * value. */
4050 if (what == LC_ALL)
4052 vim_setenv((char_u *)"LANG", name);
4053 # ifdef WIN32
4054 /* Apparently MS-Windows printf() may cause a crash when
4055 * we give it 8-bit text while it's expecting text in the
4056 * current locale. This call avoids that. */
4057 setlocale(LC_CTYPE, "C");
4058 # endif
4060 if (what != LC_CTYPE)
4062 char_u *mname;
4063 #ifdef WIN32
4064 mname = gettext_lang(name);
4065 #else
4066 mname = name;
4067 #endif
4068 vim_setenv((char_u *)"LC_MESSAGES", mname);
4069 #ifdef FEAT_MULTI_LANG
4070 set_helplang_default(mname);
4071 #endif
4074 /* Set $LC_CTYPE, because it overrules $LANG, and
4075 * gtk_set_locale() calls setlocale() again. gnome_init()
4076 * sets $LC_CTYPE to "en_US" (that's a bug!). */
4077 if (what != VIM_LC_MESSAGES)
4078 vim_setenv((char_u *)"LC_CTYPE", name);
4079 # ifdef FEAT_GUI_GTK
4080 /* Let GTK know what locale we're using. Not sure this is
4081 * really needed... */
4082 if (gui.in_use)
4083 (void)gtk_set_locale();
4084 # endif
4087 # ifdef FEAT_EVAL
4088 /* Set v:lang, v:lc_time and v:ctype to the final result. */
4089 set_lang_var();
4090 # endif
4095 # if defined(FEAT_CMDL_COMPL) || defined(PROTO)
4097 * Function given to ExpandGeneric() to obtain the possible arguments of the
4098 * ":language" command.
4100 char_u *
4101 get_lang_arg(xp, idx)
4102 expand_T *xp UNUSED;
4103 int idx;
4105 if (idx == 0)
4106 return (char_u *)"messages";
4107 if (idx == 1)
4108 return (char_u *)"ctype";
4109 if (idx == 2)
4110 return (char_u *)"time";
4111 return NULL;
4113 # endif
4115 #endif