Add runtime update script
[MacVim.git] / src / ex_cmds2.c
bloba4f60c46d4aa9f4b93fba021a6c93cf487e23b22
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;
32 ino_t sn_ino;
33 # endif
34 # ifdef FEAT_PROFILE
35 int sn_prof_on; /* TRUE when script is/was profiled */
36 int sn_pr_force; /* forceit: profile functions in this script */
37 proftime_T sn_pr_child; /* time set when going into first child */
38 int sn_pr_nest; /* nesting for sn_pr_child */
39 /* profiling the script as a whole */
40 int sn_pr_count; /* nr of times sourced */
41 proftime_T sn_pr_total; /* time spent in script + children */
42 proftime_T sn_pr_self; /* time spent in script itself */
43 proftime_T sn_pr_start; /* time at script start */
44 proftime_T sn_pr_children; /* time in children after script start */
45 /* profiling the script per line */
46 garray_T sn_prl_ga; /* things stored for every line */
47 proftime_T sn_prl_start; /* start time for current line */
48 proftime_T sn_prl_children; /* time spent in children for this line */
49 proftime_T sn_prl_wait; /* wait start time for current line */
50 int sn_prl_idx; /* index of line being timed; -1 if none */
51 int sn_prl_execed; /* line being timed was executed */
52 # endif
53 } scriptitem_T;
55 static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL};
56 #define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
58 # ifdef FEAT_PROFILE
59 /* Struct used in sn_prl_ga for every line of a script. */
60 typedef struct sn_prl_S
62 int snp_count; /* nr of times line was executed */
63 proftime_T sn_prl_total; /* time spent in a line + children */
64 proftime_T sn_prl_self; /* time spent in a line itself */
65 } sn_prl_T;
67 # define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
68 # endif
69 #endif
71 #if defined(FEAT_EVAL) || defined(PROTO)
72 static int debug_greedy = FALSE; /* batch mode debugging: don't save
73 and restore typeahead. */
76 * do_debug(): Debug mode.
77 * Repeatedly get Ex commands, until told to continue normal execution.
79 void
80 do_debug(cmd)
81 char_u *cmd;
83 int save_msg_scroll = msg_scroll;
84 int save_State = State;
85 int save_did_emsg = did_emsg;
86 int save_cmd_silent = cmd_silent;
87 int save_msg_silent = msg_silent;
88 int save_emsg_silent = emsg_silent;
89 int save_redir_off = redir_off;
90 tasave_T typeaheadbuf;
91 int typeahead_saved = FALSE;
92 int save_ignore_script = 0;
93 # ifdef FEAT_EX_EXTRA
94 int save_ex_normal_busy;
95 # endif
96 int n;
97 char_u *cmdline = NULL;
98 char_u *p;
99 char *tail = NULL;
100 static int last_cmd = 0;
101 #define CMD_CONT 1
102 #define CMD_NEXT 2
103 #define CMD_STEP 3
104 #define CMD_FINISH 4
105 #define CMD_QUIT 5
106 #define CMD_INTERRUPT 6
108 #ifdef ALWAYS_USE_GUI
109 /* Can't do this when there is no terminal for input/output. */
110 if (!gui.in_use)
112 /* Break as soon as possible. */
113 debug_break_level = 9999;
114 return;
116 #endif
118 /* Make sure we are in raw mode and start termcap mode. Might have side
119 * effects... */
120 settmode(TMODE_RAW);
121 starttermcap();
123 ++RedrawingDisabled; /* don't redisplay the window */
124 ++no_wait_return; /* don't wait for return */
125 did_emsg = FALSE; /* don't use error from debugged stuff */
126 cmd_silent = FALSE; /* display commands */
127 msg_silent = FALSE; /* display messages */
128 emsg_silent = FALSE; /* display error messages */
129 redir_off = TRUE; /* don't redirect debug commands */
131 State = NORMAL;
132 #ifdef FEAT_SNIFF
133 want_sniff_request = 0; /* No K_SNIFF wanted */
134 #endif
136 if (!debug_did_msg)
137 MSG(_("Entering Debug mode. Type \"cont\" to continue."));
138 if (sourcing_name != NULL)
139 msg(sourcing_name);
140 if (sourcing_lnum != 0)
141 smsg((char_u *)_("line %ld: %s"), (long)sourcing_lnum, cmd);
142 else
143 smsg((char_u *)_("cmd: %s"), cmd);
146 * Repeat getting a command and executing it.
148 for (;;)
150 msg_scroll = TRUE;
151 need_wait_return = FALSE;
152 #ifdef FEAT_SNIFF
153 ProcessSniffRequests();
154 #endif
155 /* Save the current typeahead buffer and replace it with an empty one.
156 * This makes sure we get input from the user here and don't interfere
157 * with the commands being executed. Reset "ex_normal_busy" to avoid
158 * the side effects of using ":normal". Save the stuff buffer and make
159 * it empty. Set ignore_script to avoid reading from script input. */
160 # ifdef FEAT_EX_EXTRA
161 save_ex_normal_busy = ex_normal_busy;
162 ex_normal_busy = 0;
163 # endif
164 if (!debug_greedy)
166 save_typeahead(&typeaheadbuf);
167 typeahead_saved = TRUE;
168 save_ignore_script = ignore_script;
169 ignore_script = TRUE;
172 cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
174 if (typeahead_saved)
176 restore_typeahead(&typeaheadbuf);
177 ignore_script = save_ignore_script;
179 # ifdef FEAT_EX_EXTRA
180 ex_normal_busy = save_ex_normal_busy;
181 # endif
183 cmdline_row = msg_row;
184 if (cmdline != NULL)
186 /* If this is a debug command, set "last_cmd".
187 * If not, reset "last_cmd".
188 * For a blank line use previous command. */
189 p = skipwhite(cmdline);
190 if (*p != NUL)
192 switch (*p)
194 case 'c': last_cmd = CMD_CONT;
195 tail = "ont";
196 break;
197 case 'n': last_cmd = CMD_NEXT;
198 tail = "ext";
199 break;
200 case 's': last_cmd = CMD_STEP;
201 tail = "tep";
202 break;
203 case 'f': last_cmd = CMD_FINISH;
204 tail = "inish";
205 break;
206 case 'q': last_cmd = CMD_QUIT;
207 tail = "uit";
208 break;
209 case 'i': last_cmd = CMD_INTERRUPT;
210 tail = "nterrupt";
211 break;
212 default: last_cmd = 0;
214 if (last_cmd != 0)
216 /* Check that the tail matches. */
217 ++p;
218 while (*p != NUL && *p == *tail)
220 ++p;
221 ++tail;
223 if (ASCII_ISALPHA(*p))
224 last_cmd = 0;
228 if (last_cmd != 0)
230 /* Execute debug command: decided where to break next and
231 * return. */
232 switch (last_cmd)
234 case CMD_CONT:
235 debug_break_level = -1;
236 break;
237 case CMD_NEXT:
238 debug_break_level = ex_nesting_level;
239 break;
240 case CMD_STEP:
241 debug_break_level = 9999;
242 break;
243 case CMD_FINISH:
244 debug_break_level = ex_nesting_level - 1;
245 break;
246 case CMD_QUIT:
247 got_int = TRUE;
248 debug_break_level = -1;
249 break;
250 case CMD_INTERRUPT:
251 got_int = TRUE;
252 debug_break_level = 9999;
253 /* Do not repeat ">interrupt" cmd, continue stepping. */
254 last_cmd = CMD_STEP;
255 break;
257 break;
260 /* don't debug this command */
261 n = debug_break_level;
262 debug_break_level = -1;
263 (void)do_cmdline(cmdline, getexline, NULL,
264 DOCMD_VERBOSE|DOCMD_EXCRESET);
265 debug_break_level = n;
267 vim_free(cmdline);
269 lines_left = Rows - 1;
271 vim_free(cmdline);
273 --RedrawingDisabled;
274 --no_wait_return;
275 redraw_all_later(NOT_VALID);
276 need_wait_return = FALSE;
277 msg_scroll = save_msg_scroll;
278 lines_left = Rows - 1;
279 State = save_State;
280 did_emsg = save_did_emsg;
281 cmd_silent = save_cmd_silent;
282 msg_silent = save_msg_silent;
283 emsg_silent = save_emsg_silent;
284 redir_off = save_redir_off;
286 /* Only print the message again when typing a command before coming back
287 * here. */
288 debug_did_msg = TRUE;
292 * ":debug".
294 void
295 ex_debug(eap)
296 exarg_T *eap;
298 int debug_break_level_save = debug_break_level;
300 debug_break_level = 9999;
301 do_cmdline_cmd(eap->arg);
302 debug_break_level = debug_break_level_save;
305 static char_u *debug_breakpoint_name = NULL;
306 static linenr_T debug_breakpoint_lnum;
309 * When debugging or a breakpoint is set on a skipped command, no debug prompt
310 * is shown by do_one_cmd(). This situation is indicated by debug_skipped, and
311 * debug_skipped_name is then set to the source name in the breakpoint case. If
312 * a skipped command decides itself that a debug prompt should be displayed, it
313 * can do so by calling dbg_check_skipped().
315 static int debug_skipped;
316 static char_u *debug_skipped_name;
319 * Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is
320 * at or below the break level. But only when the line is actually
321 * executed. Return TRUE and set breakpoint_name for skipped commands that
322 * decide to execute something themselves.
323 * Called from do_one_cmd() before executing a command.
325 void
326 dbg_check_breakpoint(eap)
327 exarg_T *eap;
329 char_u *p;
331 debug_skipped = FALSE;
332 if (debug_breakpoint_name != NULL)
334 if (!eap->skip)
336 /* replace K_SNR with "<SNR>" */
337 if (debug_breakpoint_name[0] == K_SPECIAL
338 && debug_breakpoint_name[1] == KS_EXTRA
339 && debug_breakpoint_name[2] == (int)KE_SNR)
340 p = (char_u *)"<SNR>";
341 else
342 p = (char_u *)"";
343 smsg((char_u *)_("Breakpoint in \"%s%s\" line %ld"),
345 debug_breakpoint_name + (*p == NUL ? 0 : 3),
346 (long)debug_breakpoint_lnum);
347 debug_breakpoint_name = NULL;
348 do_debug(eap->cmd);
350 else
352 debug_skipped = TRUE;
353 debug_skipped_name = debug_breakpoint_name;
354 debug_breakpoint_name = NULL;
357 else if (ex_nesting_level <= debug_break_level)
359 if (!eap->skip)
360 do_debug(eap->cmd);
361 else
363 debug_skipped = TRUE;
364 debug_skipped_name = NULL;
370 * Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was
371 * set. Return TRUE when the debug mode is entered this time.
374 dbg_check_skipped(eap)
375 exarg_T *eap;
377 int prev_got_int;
379 if (debug_skipped)
382 * Save the value of got_int and reset it. We don't want a previous
383 * interruption cause flushing the input buffer.
385 prev_got_int = got_int;
386 got_int = FALSE;
387 debug_breakpoint_name = debug_skipped_name;
388 /* eap->skip is TRUE */
389 eap->skip = FALSE;
390 (void)dbg_check_breakpoint(eap);
391 eap->skip = TRUE;
392 got_int |= prev_got_int;
393 return TRUE;
395 return FALSE;
399 * The list of breakpoints: dbg_breakp.
400 * This is a grow-array of structs.
402 struct debuggy
404 int dbg_nr; /* breakpoint number */
405 int dbg_type; /* DBG_FUNC or DBG_FILE */
406 char_u *dbg_name; /* function or file name */
407 regprog_T *dbg_prog; /* regexp program */
408 linenr_T dbg_lnum; /* line number in function or file */
409 int dbg_forceit; /* ! used */
412 static garray_T dbg_breakp = {0, 0, sizeof(struct debuggy), 4, NULL};
413 #define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx])
414 #define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx])
415 static int last_breakp = 0; /* nr of last defined breakpoint */
417 #ifdef FEAT_PROFILE
418 /* Profiling uses file and func names similar to breakpoints. */
419 static garray_T prof_ga = {0, 0, sizeof(struct debuggy), 4, NULL};
420 #endif
421 #define DBG_FUNC 1
422 #define DBG_FILE 2
424 static int dbg_parsearg __ARGS((char_u *arg, garray_T *gap));
425 static linenr_T debuggy_find __ARGS((int file,char_u *fname, linenr_T after, garray_T *gap, int *fp));
428 * Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
429 * in the entry just after the last one in dbg_breakp. Note that "dbg_name"
430 * is allocated.
431 * Returns FAIL for failure.
433 static int
434 dbg_parsearg(arg, gap)
435 char_u *arg;
436 garray_T *gap; /* either &dbg_breakp or &prof_ga */
438 char_u *p = arg;
439 char_u *q;
440 struct debuggy *bp;
441 int here = FALSE;
443 if (ga_grow(gap, 1) == FAIL)
444 return FAIL;
445 bp = &DEBUGGY(gap, gap->ga_len);
447 /* Find "func" or "file". */
448 if (STRNCMP(p, "func", 4) == 0)
449 bp->dbg_type = DBG_FUNC;
450 else if (STRNCMP(p, "file", 4) == 0)
451 bp->dbg_type = DBG_FILE;
452 else if (
453 #ifdef FEAT_PROFILE
454 gap != &prof_ga &&
455 #endif
456 STRNCMP(p, "here", 4) == 0)
458 if (curbuf->b_ffname == NULL)
460 EMSG(_(e_noname));
461 return FAIL;
463 bp->dbg_type = DBG_FILE;
464 here = TRUE;
466 else
468 EMSG2(_(e_invarg2), p);
469 return FAIL;
471 p = skipwhite(p + 4);
473 /* Find optional line number. */
474 if (here)
475 bp->dbg_lnum = curwin->w_cursor.lnum;
476 else if (
477 #ifdef FEAT_PROFILE
478 gap != &prof_ga &&
479 #endif
480 VIM_ISDIGIT(*p))
482 bp->dbg_lnum = getdigits(&p);
483 p = skipwhite(p);
485 else
486 bp->dbg_lnum = 0;
488 /* Find the function or file name. Don't accept a function name with (). */
489 if ((!here && *p == NUL)
490 || (here && *p != NUL)
491 || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL))
493 EMSG2(_(e_invarg2), arg);
494 return FAIL;
497 if (bp->dbg_type == DBG_FUNC)
498 bp->dbg_name = vim_strsave(p);
499 else if (here)
500 bp->dbg_name = vim_strsave(curbuf->b_ffname);
501 else
503 /* Expand the file name in the same way as do_source(). This means
504 * doing it twice, so that $DIR/file gets expanded when $DIR is
505 * "~/dir". */
506 #ifdef RISCOS
507 q = mch_munge_fname(p);
508 #else
509 q = expand_env_save(p);
510 #endif
511 if (q == NULL)
512 return FAIL;
513 #ifdef RISCOS
514 p = mch_munge_fname(q);
515 #else
516 p = expand_env_save(q);
517 #endif
518 vim_free(q);
519 if (p == NULL)
520 return FAIL;
521 if (*p != '*')
523 bp->dbg_name = fix_fname(p);
524 vim_free(p);
526 else
527 bp->dbg_name = p;
530 if (bp->dbg_name == NULL)
531 return FAIL;
532 return OK;
536 * ":breakadd".
538 void
539 ex_breakadd(eap)
540 exarg_T *eap;
542 struct debuggy *bp;
543 char_u *pat;
544 garray_T *gap;
546 gap = &dbg_breakp;
547 #ifdef FEAT_PROFILE
548 if (eap->cmdidx == CMD_profile)
549 gap = &prof_ga;
550 #endif
552 if (dbg_parsearg(eap->arg, gap) == OK)
554 bp = &DEBUGGY(gap, gap->ga_len);
555 bp->dbg_forceit = eap->forceit;
557 pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, FALSE);
558 if (pat != NULL)
560 bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
561 vim_free(pat);
563 if (pat == NULL || bp->dbg_prog == NULL)
564 vim_free(bp->dbg_name);
565 else
567 if (bp->dbg_lnum == 0) /* default line number is 1 */
568 bp->dbg_lnum = 1;
569 #ifdef FEAT_PROFILE
570 if (eap->cmdidx != CMD_profile)
571 #endif
573 DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
574 ++debug_tick;
576 ++gap->ga_len;
582 * ":debuggreedy".
584 void
585 ex_debuggreedy(eap)
586 exarg_T *eap;
588 if (eap->addr_count == 0 || eap->line2 != 0)
589 debug_greedy = TRUE;
590 else
591 debug_greedy = FALSE;
595 * ":breakdel" and ":profdel".
597 void
598 ex_breakdel(eap)
599 exarg_T *eap;
601 struct debuggy *bp, *bpi;
602 int nr;
603 int todel = -1;
604 int del_all = FALSE;
605 int i;
606 linenr_T best_lnum = 0;
607 garray_T *gap;
609 gap = &dbg_breakp;
610 #ifdef FEAT_PROFILE
611 if (eap->cmdidx == CMD_profdel)
612 gap = &prof_ga;
613 #endif
615 if (vim_isdigit(*eap->arg))
617 /* ":breakdel {nr}" */
618 nr = atol((char *)eap->arg);
619 for (i = 0; i < gap->ga_len; ++i)
620 if (DEBUGGY(gap, i).dbg_nr == nr)
622 todel = i;
623 break;
626 else if (*eap->arg == '*')
628 todel = 0;
629 del_all = TRUE;
631 else
633 /* ":breakdel {func|file} [lnum] {name}" */
634 if (dbg_parsearg(eap->arg, gap) == FAIL)
635 return;
636 bp = &DEBUGGY(gap, gap->ga_len);
637 for (i = 0; i < gap->ga_len; ++i)
639 bpi = &DEBUGGY(gap, i);
640 if (bp->dbg_type == bpi->dbg_type
641 && STRCMP(bp->dbg_name, bpi->dbg_name) == 0
642 && (bp->dbg_lnum == bpi->dbg_lnum
643 || (bp->dbg_lnum == 0
644 && (best_lnum == 0
645 || bpi->dbg_lnum < best_lnum))))
647 todel = i;
648 best_lnum = bpi->dbg_lnum;
651 vim_free(bp->dbg_name);
654 if (todel < 0)
655 EMSG2(_("E161: Breakpoint not found: %s"), eap->arg);
656 else
658 while (gap->ga_len > 0)
660 vim_free(DEBUGGY(gap, todel).dbg_name);
661 vim_free(DEBUGGY(gap, todel).dbg_prog);
662 --gap->ga_len;
663 if (todel < gap->ga_len)
664 mch_memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1),
665 (gap->ga_len - todel) * sizeof(struct debuggy));
666 #ifdef FEAT_PROFILE
667 if (eap->cmdidx == CMD_breakdel)
668 #endif
669 ++debug_tick;
670 if (!del_all)
671 break;
674 /* If all breakpoints were removed clear the array. */
675 if (gap->ga_len == 0)
676 ga_clear(gap);
681 * ":breaklist".
683 /*ARGSUSED*/
684 void
685 ex_breaklist(eap)
686 exarg_T *eap;
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.
1345 /*ARGSUSED*/
1347 check_changed(buf, checkaw, mult_win, forceit, allbuf)
1348 buf_T *buf;
1349 int checkaw; /* do autowrite if buffer was changed */
1350 int mult_win; /* check also when several wins for the buf */
1351 int forceit;
1352 int allbuf; /* may write all buffers */
1354 if ( !forceit
1355 && bufIsChanged(buf)
1356 && (mult_win || buf->b_nwindows <= 1)
1357 && (!checkaw || autowrite(buf, forceit) == FAIL))
1359 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1360 if ((p_confirm || cmdmod.confirm) && p_write)
1362 buf_T *buf2;
1363 int count = 0;
1365 if (allbuf)
1366 for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1367 if (bufIsChanged(buf2)
1368 && (buf2->b_ffname != NULL
1369 # ifdef FEAT_BROWSE
1370 || cmdmod.browse
1371 # endif
1373 ++count;
1374 # ifdef FEAT_AUTOCMD
1375 if (!buf_valid(buf))
1376 /* Autocommand deleted buffer, oops! It's not changed now. */
1377 return FALSE;
1378 # endif
1379 dialog_changed(buf, count > 1);
1380 # ifdef FEAT_AUTOCMD
1381 if (!buf_valid(buf))
1382 /* Autocommand deleted buffer, oops! It's not changed now. */
1383 return FALSE;
1384 # endif
1385 return bufIsChanged(buf);
1387 #endif
1388 EMSG(_(e_nowrtmsg));
1389 return TRUE;
1391 return FALSE;
1394 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO)
1396 #if defined(FEAT_BROWSE) || defined(PROTO)
1398 * When wanting to write a file without a file name, ask the user for a name.
1400 void
1401 browse_save_fname(buf)
1402 buf_T *buf;
1404 if (buf->b_fname == NULL)
1406 char_u *fname;
1408 fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"),
1409 NULL, NULL, NULL, NULL, buf);
1410 if (fname != NULL)
1412 if (setfname(buf, fname, NULL, TRUE) == OK)
1413 buf->b_flags |= BF_NOTEDITED;
1414 vim_free(fname);
1418 #endif
1421 * Ask the user what to do when abondoning a changed buffer.
1422 * Must check 'write' option first!
1424 void
1425 dialog_changed(buf, checkall)
1426 buf_T *buf;
1427 int checkall; /* may abandon all changed buffers */
1429 char_u buff[IOSIZE];
1430 int ret;
1431 buf_T *buf2;
1433 dialog_msg(buff, _("Save changes to \"%s\"?"),
1434 (buf->b_fname != NULL) ?
1435 buf->b_fname : (char_u *)_("Untitled"));
1436 if (checkall)
1437 ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
1438 else
1439 ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
1441 if (ret == VIM_YES)
1443 #ifdef FEAT_BROWSE
1444 /* May get file name, when there is none */
1445 browse_save_fname(buf);
1446 #endif
1447 if (buf->b_fname != NULL) /* didn't hit Cancel */
1448 (void)buf_write_all(buf, FALSE);
1450 else if (ret == VIM_NO)
1452 unchanged(buf, TRUE);
1454 else if (ret == VIM_ALL)
1457 * Write all modified files that can be written.
1458 * Skip readonly buffers, these need to be confirmed
1459 * individually.
1461 for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1463 if (bufIsChanged(buf2)
1464 && (buf2->b_ffname != NULL
1465 #ifdef FEAT_BROWSE
1466 || cmdmod.browse
1467 #endif
1469 && !buf2->b_p_ro)
1471 #ifdef FEAT_BROWSE
1472 /* May get file name, when there is none */
1473 browse_save_fname(buf2);
1474 #endif
1475 if (buf2->b_fname != NULL) /* didn't hit Cancel */
1476 (void)buf_write_all(buf2, FALSE);
1477 #ifdef FEAT_AUTOCMD
1478 /* an autocommand may have deleted the buffer */
1479 if (!buf_valid(buf2))
1480 buf2 = firstbuf;
1481 #endif
1485 else if (ret == VIM_DISCARDALL)
1488 * mark all buffers as unchanged
1490 for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
1491 unchanged(buf2, TRUE);
1494 #endif
1497 * Return TRUE if the buffer "buf" can be abandoned, either by making it
1498 * hidden, autowriting it or unloading it.
1501 can_abandon(buf, forceit)
1502 buf_T *buf;
1503 int forceit;
1505 return ( P_HID(buf)
1506 || !bufIsChanged(buf)
1507 || buf->b_nwindows > 1
1508 || autowrite(buf, forceit) == OK
1509 || forceit);
1513 * Return TRUE if any buffer was changed and cannot be abandoned.
1514 * That changed buffer becomes the current buffer.
1517 check_changed_any(hidden)
1518 int hidden; /* Only check hidden buffers */
1520 buf_T *buf;
1521 int save;
1522 #ifdef FEAT_WINDOWS
1523 win_T *wp;
1524 #endif
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 buf_spname(buf) != NULL ? (char_u *)buf_spname(buf) :
1566 buf->b_fname))
1568 save = no_wait_return;
1569 no_wait_return = FALSE;
1570 wait_return(FALSE);
1571 no_wait_return = save;
1575 #ifdef FEAT_WINDOWS
1576 /* Try to find a window that contains the buffer. */
1577 if (buf != curbuf)
1578 for (wp = firstwin; wp != NULL; wp = wp->w_next)
1579 if (wp->w_buffer == buf)
1581 win_goto(wp);
1582 # ifdef FEAT_AUTOCMD
1583 /* Paranoia: did autocms wipe out the buffer with changes? */
1584 if (!buf_valid(buf))
1585 return TRUE;
1586 # endif
1587 break;
1589 #endif
1591 /* Open the changed buffer in the current window. */
1592 if (buf != curbuf)
1593 set_curbuf(buf, DOBUF_GOTO);
1595 return TRUE;
1599 * return FAIL if there is no file name, OK if there is one
1600 * give error message for FAIL
1603 check_fname()
1605 if (curbuf->b_ffname == NULL)
1607 EMSG(_(e_noname));
1608 return FAIL;
1610 return OK;
1614 * flush the contents of a buffer, unless it has no file name
1616 * return FAIL for failure, OK otherwise
1619 buf_write_all(buf, forceit)
1620 buf_T *buf;
1621 int forceit;
1623 int retval;
1624 #ifdef FEAT_AUTOCMD
1625 buf_T *old_curbuf = curbuf;
1626 #endif
1628 retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
1629 (linenr_T)1, buf->b_ml.ml_line_count, NULL,
1630 FALSE, forceit, TRUE, FALSE));
1631 #ifdef FEAT_AUTOCMD
1632 if (curbuf != old_curbuf)
1634 msg_source(hl_attr(HLF_W));
1635 MSG(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
1637 #endif
1638 return retval;
1642 * Code to handle the argument list.
1645 static char_u *do_one_arg __ARGS((char_u *str));
1646 static int do_arglist __ARGS((char_u *str, int what, int after));
1647 static void alist_check_arg_idx __ARGS((void));
1648 static int editing_arg_idx __ARGS((win_T *win));
1649 #ifdef FEAT_LISTCMDS
1650 static int alist_add_list __ARGS((int count, char_u **files, int after));
1651 #endif
1652 #define AL_SET 1
1653 #define AL_ADD 2
1654 #define AL_DEL 3
1657 * Isolate one argument, taking backticks.
1658 * Changes the argument in-place, puts a NUL after it. Backticks remain.
1659 * Return a pointer to the start of the next argument.
1661 static char_u *
1662 do_one_arg(str)
1663 char_u *str;
1665 char_u *p;
1666 int inbacktick;
1668 inbacktick = FALSE;
1669 for (p = str; *str; ++str)
1671 /* When the backslash is used for escaping the special meaning of a
1672 * character we need to keep it until wildcard expansion. */
1673 if (rem_backslash(str))
1675 *p++ = *str++;
1676 *p++ = *str;
1678 else
1680 /* An item ends at a space not in backticks */
1681 if (!inbacktick && vim_isspace(*str))
1682 break;
1683 if (*str == '`')
1684 inbacktick ^= TRUE;
1685 *p++ = *str;
1688 str = skipwhite(str);
1689 *p = NUL;
1691 return str;
1695 * Separate the arguments in "str" and return a list of pointers in the
1696 * growarray "gap".
1699 get_arglist(gap, str)
1700 garray_T *gap;
1701 char_u *str;
1703 ga_init2(gap, (int)sizeof(char_u *), 20);
1704 while (*str != NUL)
1706 if (ga_grow(gap, 1) == FAIL)
1708 ga_clear(gap);
1709 return FAIL;
1711 ((char_u **)gap->ga_data)[gap->ga_len++] = str;
1713 /* Isolate one argument, change it in-place, put a NUL after it. */
1714 str = do_one_arg(str);
1716 return OK;
1719 #if defined(FEAT_QUICKFIX) || defined(FEAT_SYN_HL) || defined(PROTO)
1721 * Parse a list of arguments (file names), expand them and return in
1722 * "fnames[fcountp]".
1723 * Return FAIL or OK.
1726 get_arglist_exp(str, fcountp, fnamesp)
1727 char_u *str;
1728 int *fcountp;
1729 char_u ***fnamesp;
1731 garray_T ga;
1732 int i;
1734 if (get_arglist(&ga, str) == FAIL)
1735 return FAIL;
1736 i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
1737 fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
1738 ga_clear(&ga);
1739 return i;
1741 #endif
1743 #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
1745 * Redefine the argument list.
1747 void
1748 set_arglist(str)
1749 char_u *str;
1751 do_arglist(str, AL_SET, 0);
1753 #endif
1756 * "what" == AL_SET: Redefine the argument list to 'str'.
1757 * "what" == AL_ADD: add files in 'str' to the argument list after "after".
1758 * "what" == AL_DEL: remove files in 'str' from the argument list.
1760 * Return FAIL for failure, OK otherwise.
1762 /*ARGSUSED*/
1763 static int
1764 do_arglist(str, what, after)
1765 char_u *str;
1766 int what;
1767 int after; /* 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 /*ARGSUSED*/
2553 static void
2554 source_callback(fname, cookie)
2555 char_u *fname;
2556 void *cookie;
2558 (void)do_source(fname, FALSE, DOSO_NONE);
2562 * Source the file "name" from all directories in 'runtimepath'.
2563 * "name" can contain wildcards.
2564 * When "all" is TRUE, source all files, otherwise only the first one.
2565 * return FAIL when no file could be sourced, OK otherwise.
2568 source_runtime(name, all)
2569 char_u *name;
2570 int all;
2572 return do_in_runtimepath(name, all, source_callback, NULL);
2576 * Find "name" in 'runtimepath'. When found, invoke the callback function for
2577 * it: callback(fname, "cookie")
2578 * When "all" is TRUE repeat for all matches, otherwise only the first one is
2579 * used.
2580 * Returns OK when at least one match found, FAIL otherwise.
2583 do_in_runtimepath(name, all, callback, cookie)
2584 char_u *name;
2585 int all;
2586 void (*callback)__ARGS((char_u *fname, void *ck));
2587 void *cookie;
2589 char_u *rtp;
2590 char_u *np;
2591 char_u *buf;
2592 char_u *rtp_copy;
2593 char_u *tail;
2594 int num_files;
2595 char_u **files;
2596 int i;
2597 int did_one = FALSE;
2598 #ifdef AMIGA
2599 struct Process *proc = (struct Process *)FindTask(0L);
2600 APTR save_winptr = proc->pr_WindowPtr;
2602 /* Avoid a requester here for a volume that doesn't exist. */
2603 proc->pr_WindowPtr = (APTR)-1L;
2604 #endif
2606 /* Make a copy of 'runtimepath'. Invoking the callback may change the
2607 * value. */
2608 rtp_copy = vim_strsave(p_rtp);
2609 buf = alloc(MAXPATHL);
2610 if (buf != NULL && rtp_copy != NULL)
2612 if (p_verbose > 1)
2614 verbose_enter();
2615 smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
2616 (char *)name, (char *)p_rtp);
2617 verbose_leave();
2620 /* Loop over all entries in 'runtimepath'. */
2621 rtp = rtp_copy;
2622 while (*rtp != NUL && (all || !did_one))
2624 /* Copy the path from 'runtimepath' to buf[]. */
2625 copy_option_part(&rtp, buf, MAXPATHL, ",");
2626 if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL)
2628 add_pathsep(buf);
2629 tail = buf + STRLEN(buf);
2631 /* Loop over all patterns in "name" */
2632 np = name;
2633 while (*np != NUL && (all || !did_one))
2635 /* Append the pattern from "name" to buf[]. */
2636 copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)),
2637 "\t ");
2639 if (p_verbose > 2)
2641 verbose_enter();
2642 smsg((char_u *)_("Searching for \"%s\""), buf);
2643 verbose_leave();
2646 /* Expand wildcards, invoke the callback for each match. */
2647 if (gen_expand_wildcards(1, &buf, &num_files, &files,
2648 EW_FILE) == OK)
2650 for (i = 0; i < num_files; ++i)
2652 (*callback)(files[i], cookie);
2653 did_one = TRUE;
2654 if (!all)
2655 break;
2657 FreeWild(num_files, files);
2663 vim_free(buf);
2664 vim_free(rtp_copy);
2665 if (p_verbose > 0 && !did_one)
2667 verbose_enter();
2668 smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name);
2669 verbose_leave();
2672 #ifdef AMIGA
2673 proc->pr_WindowPtr = save_winptr;
2674 #endif
2676 return did_one ? OK : FAIL;
2679 #if defined(FEAT_EVAL) && defined(FEAT_AUTOCMD)
2681 * ":options"
2683 /*ARGSUSED*/
2684 void
2685 ex_options(eap)
2686 exarg_T *eap;
2688 cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
2690 #endif
2693 * ":source {fname}"
2695 void
2696 ex_source(eap)
2697 exarg_T *eap;
2699 #ifdef FEAT_BROWSE
2700 if (cmdmod.browse)
2702 char_u *fname = NULL;
2704 fname = do_browse(0, (char_u *)_("Source Vim script"), eap->arg,
2705 NULL, NULL, BROWSE_FILTER_MACROS, NULL);
2706 if (fname != NULL)
2708 cmd_source(fname, eap);
2709 vim_free(fname);
2712 else
2713 #endif
2714 cmd_source(eap->arg, eap);
2717 static void
2718 cmd_source(fname, eap)
2719 char_u *fname;
2720 exarg_T *eap;
2722 if (*fname == NUL)
2723 EMSG(_(e_argreq));
2725 else if (eap != NULL && eap->forceit)
2726 /* ":source!": read Normal mdoe commands
2727 * Need to execute the commands directly. This is required at least
2728 * for:
2729 * - ":g" command busy
2730 * - after ":argdo", ":windo" or ":bufdo"
2731 * - another command follows
2732 * - inside a loop
2734 openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL
2735 #ifdef FEAT_EVAL
2736 || eap->cstack->cs_idx >= 0
2737 #endif
2740 /* ":source" read ex commands */
2741 else if (do_source(fname, FALSE, DOSO_NONE) == FAIL)
2742 EMSG2(_(e_notopen), fname);
2746 * ":source" and associated commands.
2749 * Structure used to store info for each sourced file.
2750 * It is shared between do_source() and getsourceline().
2751 * This is required, because it needs to be handed to do_cmdline() and
2752 * sourcing can be done recursively.
2754 struct source_cookie
2756 FILE *fp; /* opened file for sourcing */
2757 char_u *nextline; /* if not NULL: line that was read ahead */
2758 int finished; /* ":finish" used */
2759 #if defined (USE_CRNL) || defined (USE_CR)
2760 int fileformat; /* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
2761 int error; /* TRUE if LF found after CR-LF */
2762 #endif
2763 #ifdef FEAT_EVAL
2764 linenr_T breakpoint; /* next line with breakpoint or zero */
2765 char_u *fname; /* name of sourced file */
2766 int dbg_tick; /* debug_tick when breakpoint was set */
2767 int level; /* top nesting level of sourced file */
2768 #endif
2769 #ifdef FEAT_MBYTE
2770 vimconv_T conv; /* type of conversion */
2771 #endif
2774 #ifdef FEAT_EVAL
2776 * Return the address holding the next breakpoint line for a source cookie.
2778 linenr_T *
2779 source_breakpoint(cookie)
2780 void *cookie;
2782 return &((struct source_cookie *)cookie)->breakpoint;
2786 * Return the address holding the debug tick for a source cookie.
2788 int *
2789 source_dbg_tick(cookie)
2790 void *cookie;
2792 return &((struct source_cookie *)cookie)->dbg_tick;
2796 * Return the nesting level for a source cookie.
2799 source_level(cookie)
2800 void *cookie;
2802 return ((struct source_cookie *)cookie)->level;
2804 #endif
2806 static char_u *get_one_sourceline __ARGS((struct source_cookie *sp));
2808 #if defined(WIN32) && defined(FEAT_CSCOPE)
2809 static FILE *fopen_noinh_readbin __ARGS((char *filename));
2812 * Special function to open a file without handle inheritance.
2814 static FILE *
2815 fopen_noinh_readbin(filename)
2816 char *filename;
2818 int fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0);
2820 if (fd_tmp == -1)
2821 return NULL;
2822 return fdopen(fd_tmp, READBIN);
2824 #endif
2828 * do_source: Read the file "fname" and execute its lines as EX commands.
2830 * This function may be called recursively!
2832 * return FAIL if file could not be opened, OK otherwise
2835 do_source(fname, check_other, is_vimrc)
2836 char_u *fname;
2837 int check_other; /* check for .vimrc and _vimrc */
2838 int is_vimrc; /* DOSO_ value */
2840 struct source_cookie cookie;
2841 char_u *save_sourcing_name;
2842 linenr_T save_sourcing_lnum;
2843 char_u *p;
2844 char_u *fname_exp;
2845 char_u *firstline = NULL;
2846 int retval = FAIL;
2847 #ifdef FEAT_EVAL
2848 scid_T save_current_SID;
2849 static scid_T last_current_SID = 0;
2850 void *save_funccalp;
2851 int save_debug_break_level = debug_break_level;
2852 scriptitem_T *si = NULL;
2853 # ifdef UNIX
2854 struct stat st;
2855 int stat_ok;
2856 # endif
2857 #endif
2858 #ifdef STARTUPTIME
2859 struct timeval tv_rel;
2860 struct timeval tv_start;
2861 #endif
2862 #ifdef FEAT_PROFILE
2863 proftime_T wait_start;
2864 #endif
2866 #ifdef RISCOS
2867 p = mch_munge_fname(fname);
2868 #else
2869 p = expand_env_save(fname);
2870 #endif
2871 if (p == NULL)
2872 return retval;
2873 fname_exp = fix_fname(p);
2874 vim_free(p);
2875 if (fname_exp == NULL)
2876 return retval;
2877 if (mch_isdir(fname_exp))
2879 smsg((char_u *)_("Cannot source a directory: \"%s\""), fname);
2880 goto theend;
2883 #ifdef FEAT_AUTOCMD
2884 /* Apply SourceCmd autocommands, they should get the file and source it. */
2885 if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
2886 && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
2887 FALSE, curbuf))
2889 # ifdef FEAT_EVAL
2890 retval = aborting() ? FAIL : OK;
2891 # else
2892 retval = OK;
2893 # endif
2894 goto theend;
2897 /* Apply SourcePre autocommands, they may get the file. */
2898 apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
2899 #endif
2901 #if defined(WIN32) && defined(FEAT_CSCOPE)
2902 cookie.fp = fopen_noinh_readbin((char *)fname_exp);
2903 #else
2904 cookie.fp = mch_fopen((char *)fname_exp, READBIN);
2905 #endif
2906 if (cookie.fp == NULL && check_other)
2909 * Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
2910 * and ".exrc" by "_exrc" or vice versa.
2912 p = gettail(fname_exp);
2913 if ((*p == '.' || *p == '_')
2914 && (STRICMP(p + 1, "vimrc") == 0
2915 || STRICMP(p + 1, "gvimrc") == 0
2916 || STRICMP(p + 1, "exrc") == 0))
2918 if (*p == '_')
2919 *p = '.';
2920 else
2921 *p = '_';
2922 #if defined(WIN32) && defined(FEAT_CSCOPE)
2923 cookie.fp = fopen_noinh_readbin((char *)fname_exp);
2924 #else
2925 cookie.fp = mch_fopen((char *)fname_exp, READBIN);
2926 #endif
2930 if (cookie.fp == NULL)
2932 if (p_verbose > 0)
2934 verbose_enter();
2935 if (sourcing_name == NULL)
2936 smsg((char_u *)_("could not source \"%s\""), fname);
2937 else
2938 smsg((char_u *)_("line %ld: could not source \"%s\""),
2939 sourcing_lnum, fname);
2940 verbose_leave();
2942 goto theend;
2946 * The file exists.
2947 * - In verbose mode, give a message.
2948 * - For a vimrc file, may want to set 'compatible', call vimrc_found().
2950 if (p_verbose > 1)
2952 verbose_enter();
2953 if (sourcing_name == NULL)
2954 smsg((char_u *)_("sourcing \"%s\""), fname);
2955 else
2956 smsg((char_u *)_("line %ld: sourcing \"%s\""),
2957 sourcing_lnum, fname);
2958 verbose_leave();
2960 if (is_vimrc == DOSO_VIMRC)
2961 vimrc_found(fname_exp, (char_u *)"MYVIMRC");
2962 else if (is_vimrc == DOSO_GVIMRC)
2963 vimrc_found(fname_exp, (char_u *)"MYGVIMRC");
2965 #ifdef USE_CRNL
2966 /* If no automatic file format: Set default to CR-NL. */
2967 if (*p_ffs == NUL)
2968 cookie.fileformat = EOL_DOS;
2969 else
2970 cookie.fileformat = EOL_UNKNOWN;
2971 cookie.error = FALSE;
2972 #endif
2974 #ifdef USE_CR
2975 /* If no automatic file format: Set default to CR. */
2976 if (*p_ffs == NUL)
2977 cookie.fileformat = EOL_MAC;
2978 else
2979 cookie.fileformat = EOL_UNKNOWN;
2980 cookie.error = FALSE;
2981 #endif
2983 cookie.nextline = NULL;
2984 cookie.finished = FALSE;
2986 #ifdef FEAT_EVAL
2988 * Check if this script has a breakpoint.
2990 cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
2991 cookie.fname = fname_exp;
2992 cookie.dbg_tick = debug_tick;
2994 cookie.level = ex_nesting_level;
2995 #endif
2998 * Keep the sourcing name/lnum, for recursive calls.
3000 save_sourcing_name = sourcing_name;
3001 sourcing_name = fname_exp;
3002 save_sourcing_lnum = sourcing_lnum;
3003 sourcing_lnum = 0;
3005 #ifdef FEAT_MBYTE
3006 cookie.conv.vc_type = CONV_NONE; /* no conversion */
3008 /* Read the first line so we can check for a UTF-8 BOM. */
3009 firstline = getsourceline(0, (void *)&cookie, 0);
3010 if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
3011 && firstline[1] == 0xbb && firstline[2] == 0xbf)
3013 /* Found BOM; setup conversion, skip over BOM and recode the line. */
3014 convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
3015 p = string_convert(&cookie.conv, firstline + 3, NULL);
3016 if (p == NULL)
3017 p = vim_strsave(firstline + 3);
3018 if (p != NULL)
3020 vim_free(firstline);
3021 firstline = p;
3024 #endif
3026 #ifdef STARTUPTIME
3027 time_push(&tv_rel, &tv_start);
3028 #endif
3030 #ifdef FEAT_EVAL
3031 # ifdef FEAT_PROFILE
3032 if (do_profiling == PROF_YES)
3033 prof_child_enter(&wait_start); /* entering a child now */
3034 # endif
3036 /* Don't use local function variables, if called from a function.
3037 * Also starts profiling timer for nested script. */
3038 save_funccalp = save_funccal();
3041 * Check if this script was sourced before to finds its SID.
3042 * If it's new, generate a new SID.
3044 save_current_SID = current_SID;
3045 # ifdef UNIX
3046 stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
3047 # endif
3048 for (current_SID = script_items.ga_len; current_SID > 0; --current_SID)
3050 si = &SCRIPT_ITEM(current_SID);
3051 if (si->sn_name != NULL
3052 && (
3053 # ifdef UNIX
3054 /* Compare dev/ino when possible, it catches symbolic
3055 * links. Also compare file names, the inode may change
3056 * when the file was edited. */
3057 ((stat_ok && si->sn_dev != -1)
3058 && (si->sn_dev == st.st_dev
3059 && si->sn_ino == st.st_ino)) ||
3060 # endif
3061 fnamecmp(si->sn_name, fname_exp) == 0))
3062 break;
3064 if (current_SID == 0)
3066 current_SID = ++last_current_SID;
3067 if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len))
3068 == FAIL)
3069 goto almosttheend;
3070 while (script_items.ga_len < current_SID)
3072 ++script_items.ga_len;
3073 SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
3074 # ifdef FEAT_PROFILE
3075 SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
3076 # endif
3078 si = &SCRIPT_ITEM(current_SID);
3079 si->sn_name = fname_exp;
3080 fname_exp = NULL;
3081 # ifdef UNIX
3082 if (stat_ok)
3084 si->sn_dev = st.st_dev;
3085 si->sn_ino = st.st_ino;
3087 else
3088 si->sn_dev = -1;
3089 # endif
3091 /* Allocate the local script variables to use for this script. */
3092 new_script_vars(current_SID);
3095 # ifdef FEAT_PROFILE
3096 if (do_profiling == PROF_YES)
3098 int forceit;
3100 /* Check if we do profiling for this script. */
3101 if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit))
3103 script_do_profile(si);
3104 si->sn_pr_force = forceit;
3106 if (si->sn_prof_on)
3108 ++si->sn_pr_count;
3109 profile_start(&si->sn_pr_start);
3110 profile_zero(&si->sn_pr_children);
3113 # endif
3114 #endif
3117 * Call do_cmdline, which will call getsourceline() to get the lines.
3119 do_cmdline(firstline, getsourceline, (void *)&cookie,
3120 DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
3121 retval = OK;
3123 #ifdef FEAT_PROFILE
3124 if (do_profiling == PROF_YES)
3126 /* Get "si" again, "script_items" may have been reallocated. */
3127 si = &SCRIPT_ITEM(current_SID);
3128 if (si->sn_prof_on)
3130 profile_end(&si->sn_pr_start);
3131 profile_sub_wait(&wait_start, &si->sn_pr_start);
3132 profile_add(&si->sn_pr_total, &si->sn_pr_start);
3133 profile_self(&si->sn_pr_self, &si->sn_pr_start,
3134 &si->sn_pr_children);
3137 #endif
3139 if (got_int)
3140 EMSG(_(e_interr));
3141 sourcing_name = save_sourcing_name;
3142 sourcing_lnum = save_sourcing_lnum;
3143 if (p_verbose > 1)
3145 verbose_enter();
3146 smsg((char_u *)_("finished sourcing %s"), fname);
3147 if (sourcing_name != NULL)
3148 smsg((char_u *)_("continuing in %s"), sourcing_name);
3149 verbose_leave();
3151 #ifdef STARTUPTIME
3152 vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
3153 time_msg((char *)IObuff, &tv_start);
3154 time_pop(&tv_rel);
3155 #endif
3157 #ifdef FEAT_EVAL
3159 * After a "finish" in debug mode, need to break at first command of next
3160 * sourced file.
3162 if (save_debug_break_level > ex_nesting_level
3163 && debug_break_level == ex_nesting_level)
3164 ++debug_break_level;
3165 #endif
3167 #ifdef FEAT_EVAL
3168 almosttheend:
3169 current_SID = save_current_SID;
3170 restore_funccal(save_funccalp);
3171 # ifdef FEAT_PROFILE
3172 if (do_profiling == PROF_YES)
3173 prof_child_exit(&wait_start); /* leaving a child now */
3174 # endif
3175 #endif
3176 fclose(cookie.fp);
3177 vim_free(cookie.nextline);
3178 vim_free(firstline);
3179 #ifdef FEAT_MBYTE
3180 convert_setup(&cookie.conv, NULL, NULL);
3181 #endif
3183 theend:
3184 vim_free(fname_exp);
3185 return retval;
3188 #if defined(FEAT_EVAL) || defined(PROTO)
3191 * ":scriptnames"
3193 /*ARGSUSED*/
3194 void
3195 ex_scriptnames(eap)
3196 exarg_T *eap;
3198 int i;
3200 for (i = 1; i <= script_items.ga_len && !got_int; ++i)
3201 if (SCRIPT_ITEM(i).sn_name != NULL)
3202 smsg((char_u *)"%3d: %s", i, SCRIPT_ITEM(i).sn_name);
3205 # if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
3207 * Fix slashes in the list of script names for 'shellslash'.
3209 void
3210 scriptnames_slash_adjust()
3212 int i;
3214 for (i = 1; i <= script_items.ga_len; ++i)
3215 if (SCRIPT_ITEM(i).sn_name != NULL)
3216 slash_adjust(SCRIPT_ITEM(i).sn_name);
3218 # endif
3221 * Get a pointer to a script name. Used for ":verbose set".
3223 char_u *
3224 get_scriptname(id)
3225 scid_T id;
3227 if (id == SID_MODELINE)
3228 return (char_u *)_("modeline");
3229 if (id == SID_CMDARG)
3230 return (char_u *)_("--cmd argument");
3231 if (id == SID_CARG)
3232 return (char_u *)_("-c argument");
3233 if (id == SID_ENV)
3234 return (char_u *)_("environment variable");
3235 if (id == SID_ERROR)
3236 return (char_u *)_("error handler");
3237 return SCRIPT_ITEM(id).sn_name;
3240 # if defined(EXITFREE) || defined(PROTO)
3241 void
3242 free_scriptnames()
3244 int i;
3246 for (i = script_items.ga_len; i > 0; --i)
3247 vim_free(SCRIPT_ITEM(i).sn_name);
3248 ga_clear(&script_items);
3250 # endif
3252 #endif
3254 #if defined(USE_CR) || defined(PROTO)
3256 # if defined(__MSL__) && (__MSL__ >= 22)
3258 * Newer version of the Metrowerks library handle DOS and UNIX files
3259 * without help.
3260 * Test with earlier versions, MSL 2.2 is the library supplied with
3261 * Codewarrior Pro 2.
3263 char *
3264 fgets_cr(s, n, stream)
3265 char *s;
3266 int n;
3267 FILE *stream;
3269 return fgets(s, n, stream);
3271 # else
3273 * Version of fgets() which also works for lines ending in a <CR> only
3274 * (Macintosh format).
3275 * For older versions of the Metrowerks library.
3276 * At least CodeWarrior 9 needed this code.
3278 char *
3279 fgets_cr(s, n, stream)
3280 char *s;
3281 int n;
3282 FILE *stream;
3284 int c = 0;
3285 int char_read = 0;
3287 while (!feof(stream) && c != '\r' && c != '\n' && char_read < n - 1)
3289 c = fgetc(stream);
3290 s[char_read++] = c;
3291 /* If the file is in DOS format, we need to skip a NL after a CR. I
3292 * thought it was the other way around, but this appears to work... */
3293 if (c == '\n')
3295 c = fgetc(stream);
3296 if (c != '\r')
3297 ungetc(c, stream);
3301 s[char_read] = 0;
3302 if (char_read == 0)
3303 return NULL;
3305 if (feof(stream) && char_read == 1)
3306 return NULL;
3308 return s;
3310 # endif
3311 #endif
3314 * Get one full line from a sourced file.
3315 * Called by do_cmdline() when it's called from do_source().
3317 * Return a pointer to the line in allocated memory.
3318 * Return NULL for end-of-file or some error.
3320 /* ARGSUSED */
3321 char_u *
3322 getsourceline(c, cookie, indent)
3323 int c; /* not used */
3324 void *cookie;
3325 int indent; /* not used */
3327 struct source_cookie *sp = (struct source_cookie *)cookie;
3328 char_u *line;
3329 char_u *p, *s;
3331 #ifdef FEAT_EVAL
3332 /* If breakpoints have been added/deleted need to check for it. */
3333 if (sp->dbg_tick < debug_tick)
3335 sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
3336 sp->dbg_tick = debug_tick;
3338 # ifdef FEAT_PROFILE
3339 if (do_profiling == PROF_YES)
3340 script_line_end();
3341 # endif
3342 #endif
3344 * Get current line. If there is a read-ahead line, use it, otherwise get
3345 * one now.
3347 if (sp->finished)
3348 line = NULL;
3349 else if (sp->nextline == NULL)
3350 line = get_one_sourceline(sp);
3351 else
3353 line = sp->nextline;
3354 sp->nextline = NULL;
3355 ++sourcing_lnum;
3357 #ifdef FEAT_PROFILE
3358 if (line != NULL && do_profiling == PROF_YES)
3359 script_line_start();
3360 #endif
3362 /* Only concatenate lines starting with a \ when 'cpoptions' doesn't
3363 * contain the 'C' flag. */
3364 if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL))
3366 /* compensate for the one line read-ahead */
3367 --sourcing_lnum;
3368 for (;;)
3370 sp->nextline = get_one_sourceline(sp);
3371 if (sp->nextline == NULL)
3372 break;
3373 p = skipwhite(sp->nextline);
3374 if (*p != '\\')
3375 break;
3376 s = alloc((int)(STRLEN(line) + STRLEN(p)));
3377 if (s == NULL) /* out of memory */
3378 break;
3379 STRCPY(s, line);
3380 STRCAT(s, p + 1);
3381 vim_free(line);
3382 line = s;
3383 vim_free(sp->nextline);
3387 #ifdef FEAT_MBYTE
3388 if (line != NULL && sp->conv.vc_type != CONV_NONE)
3390 /* Convert the encoding of the script line. */
3391 s = string_convert(&sp->conv, line, NULL);
3392 if (s != NULL)
3394 vim_free(line);
3395 line = s;
3398 #endif
3400 #ifdef FEAT_EVAL
3401 /* Did we encounter a breakpoint? */
3402 if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
3404 dbg_breakpoint(sp->fname, sourcing_lnum);
3405 /* Find next breakpoint. */
3406 sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
3407 sp->dbg_tick = debug_tick;
3409 #endif
3411 return line;
3414 static char_u *
3415 get_one_sourceline(sp)
3416 struct source_cookie *sp;
3418 garray_T ga;
3419 int len;
3420 int c;
3421 char_u *buf;
3422 #ifdef USE_CRNL
3423 int has_cr; /* CR-LF found */
3424 #endif
3425 #ifdef USE_CR
3426 char_u *scan;
3427 #endif
3428 int have_read = FALSE;
3430 /* use a growarray to store the sourced line */
3431 ga_init2(&ga, 1, 250);
3434 * Loop until there is a finished line (or end-of-file).
3436 sourcing_lnum++;
3437 for (;;)
3439 /* make room to read at least 120 (more) characters */
3440 if (ga_grow(&ga, 120) == FAIL)
3441 break;
3442 buf = (char_u *)ga.ga_data;
3444 #ifdef USE_CR
3445 if (sp->fileformat == EOL_MAC)
3447 if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
3448 sp->fp) == NULL)
3449 break;
3451 else
3452 #endif
3453 if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
3454 sp->fp) == NULL)
3455 break;
3456 len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
3457 #ifdef USE_CRNL
3458 /* Ignore a trailing CTRL-Z, when in Dos mode. Only recognize the
3459 * CTRL-Z by its own, or after a NL. */
3460 if ( (len == 1 || (len >= 2 && buf[len - 2] == '\n'))
3461 && sp->fileformat == EOL_DOS
3462 && buf[len - 1] == Ctrl_Z)
3464 buf[len - 1] = NUL;
3465 break;
3467 #endif
3469 #ifdef USE_CR
3470 /* If the read doesn't stop on a new line, and there's
3471 * some CR then we assume a Mac format */
3472 if (sp->fileformat == EOL_UNKNOWN)
3474 if (buf[len - 1] != '\n' && vim_strchr(buf, '\r') != NULL)
3475 sp->fileformat = EOL_MAC;
3476 else
3477 sp->fileformat = EOL_UNIX;
3480 if (sp->fileformat == EOL_MAC)
3482 scan = vim_strchr(buf, '\r');
3484 if (scan != NULL)
3486 *scan = '\n';
3487 if (*(scan + 1) != 0)
3489 *(scan + 1) = 0;
3490 fseek(sp->fp, (long)(scan - buf - len + 1), SEEK_CUR);
3493 len = STRLEN(buf);
3495 #endif
3497 have_read = TRUE;
3498 ga.ga_len = len;
3500 /* If the line was longer than the buffer, read more. */
3501 if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
3502 continue;
3504 if (len >= 1 && buf[len - 1] == '\n') /* remove trailing NL */
3506 #ifdef USE_CRNL
3507 has_cr = (len >= 2 && buf[len - 2] == '\r');
3508 if (sp->fileformat == EOL_UNKNOWN)
3510 if (has_cr)
3511 sp->fileformat = EOL_DOS;
3512 else
3513 sp->fileformat = EOL_UNIX;
3516 if (sp->fileformat == EOL_DOS)
3518 if (has_cr) /* replace trailing CR */
3520 buf[len - 2] = '\n';
3521 --len;
3522 --ga.ga_len;
3524 else /* lines like ":map xx yy^M" will have failed */
3526 if (!sp->error)
3528 msg_source(hl_attr(HLF_W));
3529 EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
3531 sp->error = TRUE;
3532 sp->fileformat = EOL_UNIX;
3535 #endif
3536 /* The '\n' is escaped if there is an odd number of ^V's just
3537 * before it, first set "c" just before the 'V's and then check
3538 * len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo */
3539 for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--)
3541 if ((len & 1) != (c & 1)) /* escaped NL, read more */
3543 sourcing_lnum++;
3544 continue;
3547 buf[len - 1] = NUL; /* remove the NL */
3551 * Check for ^C here now and then, so recursive :so can be broken.
3553 line_breakcheck();
3554 break;
3557 if (have_read)
3558 return (char_u *)ga.ga_data;
3560 vim_free(ga.ga_data);
3561 return NULL;
3564 #if defined(FEAT_PROFILE) || defined(PROTO)
3566 * Called when starting to read a script line.
3567 * "sourcing_lnum" must be correct!
3568 * When skipping lines it may not actually be executed, but we won't find out
3569 * until later and we need to store the time now.
3571 void
3572 script_line_start()
3574 scriptitem_T *si;
3575 sn_prl_T *pp;
3577 if (current_SID <= 0 || current_SID > script_items.ga_len)
3578 return;
3579 si = &SCRIPT_ITEM(current_SID);
3580 if (si->sn_prof_on && sourcing_lnum >= 1)
3582 /* Grow the array before starting the timer, so that the time spent
3583 * here isn't counted. */
3584 ga_grow(&si->sn_prl_ga, (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
3585 si->sn_prl_idx = sourcing_lnum - 1;
3586 while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
3587 && si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
3589 /* Zero counters for a line that was not used before. */
3590 pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len);
3591 pp->snp_count = 0;
3592 profile_zero(&pp->sn_prl_total);
3593 profile_zero(&pp->sn_prl_self);
3594 ++si->sn_prl_ga.ga_len;
3596 si->sn_prl_execed = FALSE;
3597 profile_start(&si->sn_prl_start);
3598 profile_zero(&si->sn_prl_children);
3599 profile_get_wait(&si->sn_prl_wait);
3604 * Called when actually executing a function line.
3606 void
3607 script_line_exec()
3609 scriptitem_T *si;
3611 if (current_SID <= 0 || current_SID > script_items.ga_len)
3612 return;
3613 si = &SCRIPT_ITEM(current_SID);
3614 if (si->sn_prof_on && si->sn_prl_idx >= 0)
3615 si->sn_prl_execed = TRUE;
3619 * Called when done with a function line.
3621 void
3622 script_line_end()
3624 scriptitem_T *si;
3625 sn_prl_T *pp;
3627 if (current_SID <= 0 || current_SID > script_items.ga_len)
3628 return;
3629 si = &SCRIPT_ITEM(current_SID);
3630 if (si->sn_prof_on && si->sn_prl_idx >= 0
3631 && si->sn_prl_idx < si->sn_prl_ga.ga_len)
3633 if (si->sn_prl_execed)
3635 pp = &PRL_ITEM(si, si->sn_prl_idx);
3636 ++pp->snp_count;
3637 profile_end(&si->sn_prl_start);
3638 profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start);
3639 profile_add(&pp->sn_prl_total, &si->sn_prl_start);
3640 profile_self(&pp->sn_prl_self, &si->sn_prl_start,
3641 &si->sn_prl_children);
3643 si->sn_prl_idx = -1;
3646 #endif
3649 * ":scriptencoding": Set encoding conversion for a sourced script.
3650 * Without the multi-byte feature it's simply ignored.
3652 /*ARGSUSED*/
3653 void
3654 ex_scriptencoding(eap)
3655 exarg_T *eap;
3657 #ifdef FEAT_MBYTE
3658 struct source_cookie *sp;
3659 char_u *name;
3661 if (!getline_equal(eap->getline, eap->cookie, getsourceline))
3663 EMSG(_("E167: :scriptencoding used outside of a sourced file"));
3664 return;
3667 if (*eap->arg != NUL)
3669 name = enc_canonize(eap->arg);
3670 if (name == NULL) /* out of memory */
3671 return;
3673 else
3674 name = eap->arg;
3676 /* Setup for conversion from the specified encoding to 'encoding'. */
3677 sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie);
3678 convert_setup(&sp->conv, name, p_enc);
3680 if (name != eap->arg)
3681 vim_free(name);
3682 #endif
3685 #if defined(FEAT_EVAL) || defined(PROTO)
3687 * ":finish": Mark a sourced file as finished.
3689 void
3690 ex_finish(eap)
3691 exarg_T *eap;
3693 if (getline_equal(eap->getline, eap->cookie, getsourceline))
3694 do_finish(eap, FALSE);
3695 else
3696 EMSG(_("E168: :finish used outside of a sourced file"));
3700 * Mark a sourced file as finished. Possibly makes the ":finish" pending.
3701 * Also called for a pending finish at the ":endtry" or after returning from
3702 * an extra do_cmdline(). "reanimate" is used in the latter case.
3704 void
3705 do_finish(eap, reanimate)
3706 exarg_T *eap;
3707 int reanimate;
3709 int idx;
3711 if (reanimate)
3712 ((struct source_cookie *)getline_cookie(eap->getline,
3713 eap->cookie))->finished = FALSE;
3716 * Cleanup (and inactivate) conditionals, but stop when a try conditional
3717 * not in its finally clause (which then is to be executed next) is found.
3718 * In this case, make the ":finish" pending for execution at the ":endtry".
3719 * Otherwise, finish normally.
3721 idx = cleanup_conditionals(eap->cstack, 0, TRUE);
3722 if (idx >= 0)
3724 eap->cstack->cs_pending[idx] = CSTP_FINISH;
3725 report_make_pending(CSTP_FINISH, NULL);
3727 else
3728 ((struct source_cookie *)getline_cookie(eap->getline,
3729 eap->cookie))->finished = TRUE;
3734 * Return TRUE when a sourced file had the ":finish" command: Don't give error
3735 * message for missing ":endif".
3736 * Return FALSE when not sourcing a file.
3739 source_finished(fgetline, cookie)
3740 char_u *(*fgetline) __ARGS((int, void *, int));
3741 void *cookie;
3743 return (getline_equal(fgetline, cookie, getsourceline)
3744 && ((struct source_cookie *)getline_cookie(
3745 fgetline, cookie))->finished);
3747 #endif
3749 #if defined(FEAT_LISTCMDS) || defined(PROTO)
3751 * ":checktime [buffer]"
3753 void
3754 ex_checktime(eap)
3755 exarg_T *eap;
3757 buf_T *buf;
3758 int save_no_check_timestamps = no_check_timestamps;
3760 no_check_timestamps = 0;
3761 if (eap->addr_count == 0) /* default is all buffers */
3762 check_timestamps(FALSE);
3763 else
3765 buf = buflist_findnr((int)eap->line2);
3766 if (buf != NULL) /* cannot happen? */
3767 (void)buf_check_timestamp(buf, FALSE);
3769 no_check_timestamps = save_no_check_timestamps;
3771 #endif
3773 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3774 && (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG))
3775 static char *get_locale_val __ARGS((int what));
3777 static char *
3778 get_locale_val(what)
3779 int what;
3781 char *loc;
3783 /* Obtain the locale value from the libraries. For DJGPP this is
3784 * redefined and it doesn't use the arguments. */
3785 loc = setlocale(what, NULL);
3787 # ifdef WIN32
3788 if (loc != NULL)
3790 char_u *p;
3792 /* setocale() returns something like "LC_COLLATE=<name>;LC_..." when
3793 * one of the values (e.g., LC_CTYPE) differs. */
3794 p = vim_strchr(loc, '=');
3795 if (p != NULL)
3797 loc = ++p;
3798 while (*p != NUL) /* remove trailing newline */
3800 if (*p < ' ' || *p == ';')
3802 *p = NUL;
3803 break;
3805 ++p;
3809 # endif
3811 return loc;
3813 #endif
3816 #ifdef WIN32
3818 * On MS-Windows locale names are strings like "German_Germany.1252", but
3819 * gettext expects "de". Try to translate one into another here for a few
3820 * supported languages.
3822 static char_u *
3823 gettext_lang(char_u *name)
3825 int i;
3826 static char *(mtable[]) = {
3827 "afrikaans", "af",
3828 "czech", "cs",
3829 "dutch", "nl",
3830 "german", "de",
3831 "english_united kingdom", "en_GB",
3832 "spanish", "es",
3833 "french", "fr",
3834 "italian", "it",
3835 "japanese", "ja",
3836 "korean", "ko",
3837 "norwegian", "no",
3838 "polish", "pl",
3839 "russian", "ru",
3840 "slovak", "sk",
3841 "swedish", "sv",
3842 "ukrainian", "uk",
3843 "chinese_china", "zh_CN",
3844 "chinese_taiwan", "zh_TW",
3845 NULL};
3847 for (i = 0; mtable[i] != NULL; i += 2)
3848 if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0)
3849 return mtable[i + 1];
3850 return name;
3852 #endif
3854 #if defined(FEAT_MULTI_LANG) || defined(PROTO)
3856 * Obtain the current messages language. Used to set the default for
3857 * 'helplang'. May return NULL or an empty string.
3859 char_u *
3860 get_mess_lang()
3862 char_u *p;
3864 # if (defined(HAVE_LOCALE_H) || defined(X_LOCALE))
3865 # if defined(LC_MESSAGES)
3866 p = (char_u *)get_locale_val(LC_MESSAGES);
3867 # else
3868 /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
3869 * may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME
3870 * and LC_MONETARY may be set differently for a Japanese working in the
3871 * US. */
3872 p = (char_u *)get_locale_val(LC_COLLATE);
3873 # endif
3874 # else
3875 p = mch_getenv((char_u *)"LC_ALL");
3876 if (p == NULL || *p == NUL)
3878 p = mch_getenv((char_u *)"LC_MESSAGES");
3879 if (p == NULL || *p == NUL)
3880 p = mch_getenv((char_u *)"LANG");
3882 # endif
3883 # ifdef WIN32
3884 p = gettext_lang(p);
3885 # endif
3886 return p;
3888 #endif
3890 /* Complicated #if; matches with where get_mess_env() is used below. */
3891 #if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3892 && defined(LC_MESSAGES))) \
3893 || ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3894 && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) \
3895 && !defined(LC_MESSAGES))
3896 static char_u *get_mess_env __ARGS((void));
3899 * Get the language used for messages from the environment.
3901 static char_u *
3902 get_mess_env()
3904 char_u *p;
3906 p = mch_getenv((char_u *)"LC_ALL");
3907 if (p == NULL || *p == NUL)
3909 p = mch_getenv((char_u *)"LC_MESSAGES");
3910 if (p == NULL || *p == NUL)
3912 p = mch_getenv((char_u *)"LANG");
3913 if (p != NULL && VIM_ISDIGIT(*p))
3914 p = NULL; /* ignore something like "1043" */
3915 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3916 if (p == NULL || *p == NUL)
3917 p = (char_u *)get_locale_val(LC_CTYPE);
3918 # endif
3921 return p;
3923 #endif
3925 #if defined(FEAT_EVAL) || defined(PROTO)
3928 * Set the "v:lang" variable according to the current locale setting.
3929 * Also do "v:lc_time"and "v:ctype".
3931 void
3932 set_lang_var()
3934 char_u *loc;
3936 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3937 loc = (char_u *)get_locale_val(LC_CTYPE);
3938 # else
3939 /* setlocale() not supported: use the default value */
3940 loc = (char_u *)"C";
3941 # endif
3942 set_vim_var_string(VV_CTYPE, loc, -1);
3944 /* When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
3945 * back to LC_CTYPE if it's empty. */
3946 # if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) && defined(LC_MESSAGES)
3947 loc = (char_u *)get_locale_val(LC_MESSAGES);
3948 # else
3949 loc = get_mess_env();
3950 # endif
3951 set_vim_var_string(VV_LANG, loc, -1);
3953 # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
3954 loc = (char_u *)get_locale_val(LC_TIME);
3955 # endif
3956 set_vim_var_string(VV_LC_TIME, loc, -1);
3958 #endif
3960 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
3961 && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
3963 * ":language": Set the language (locale).
3965 void
3966 ex_language(eap)
3967 exarg_T *eap;
3969 char *loc;
3970 char_u *p;
3971 char_u *name;
3972 int what = LC_ALL;
3973 char *whatstr = "";
3974 #ifdef LC_MESSAGES
3975 # define VIM_LC_MESSAGES LC_MESSAGES
3976 #else
3977 # define VIM_LC_MESSAGES 6789
3978 #endif
3980 name = eap->arg;
3982 /* Check for "messages {name}", "ctype {name}" or "time {name}" argument.
3983 * Allow abbreviation, but require at least 3 characters to avoid
3984 * confusion with a two letter language name "me" or "ct". */
3985 p = skiptowhite(eap->arg);
3986 if ((*p == NUL || vim_iswhite(*p)) && p - eap->arg >= 3)
3988 if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0)
3990 what = VIM_LC_MESSAGES;
3991 name = skipwhite(p);
3992 whatstr = "messages ";
3994 else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0)
3996 what = LC_CTYPE;
3997 name = skipwhite(p);
3998 whatstr = "ctype ";
4000 else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0)
4002 what = LC_TIME;
4003 name = skipwhite(p);
4004 whatstr = "time ";
4008 if (*name == NUL)
4010 #ifndef LC_MESSAGES
4011 if (what == VIM_LC_MESSAGES)
4012 p = get_mess_env();
4013 else
4014 #endif
4015 p = (char_u *)setlocale(what, NULL);
4016 if (p == NULL || *p == NUL)
4017 p = (char_u *)"Unknown";
4018 smsg((char_u *)_("Current %slanguage: \"%s\""), whatstr, p);
4020 else
4022 #ifndef LC_MESSAGES
4023 if (what == VIM_LC_MESSAGES)
4024 loc = "";
4025 else
4026 #endif
4028 loc = setlocale(what, (char *)name);
4029 #if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
4030 /* Make sure strtod() uses a decimal point, not a comma. */
4031 setlocale(LC_NUMERIC, "C");
4032 #endif
4034 if (loc == NULL)
4035 EMSG2(_("E197: Cannot set language to \"%s\""), name);
4036 else
4038 #ifdef HAVE_NL_MSG_CAT_CNTR
4039 /* Need to do this for GNU gettext, otherwise cached translations
4040 * will be used again. */
4041 extern int _nl_msg_cat_cntr;
4043 ++_nl_msg_cat_cntr;
4044 #endif
4045 /* Reset $LC_ALL, otherwise it would overrule everything. */
4046 vim_setenv((char_u *)"LC_ALL", (char_u *)"");
4048 if (what != LC_TIME)
4050 /* Tell gettext() what to translate to. It apparently doesn't
4051 * use the currently effective locale. Also do this when
4052 * FEAT_GETTEXT isn't defined, so that shell commands use this
4053 * value. */
4054 if (what == LC_ALL)
4056 vim_setenv((char_u *)"LANG", name);
4057 # ifdef WIN32
4058 /* Apparently MS-Windows printf() may cause a crash when
4059 * we give it 8-bit text while it's expecting text in the
4060 * current locale. This call avoids that. */
4061 setlocale(LC_CTYPE, "C");
4062 # endif
4064 if (what != LC_CTYPE)
4066 char_u *mname;
4067 #ifdef WIN32
4068 mname = gettext_lang(name);
4069 #else
4070 mname = name;
4071 #endif
4072 vim_setenv((char_u *)"LC_MESSAGES", mname);
4073 #ifdef FEAT_MULTI_LANG
4074 set_helplang_default(mname);
4075 #endif
4078 /* Set $LC_CTYPE, because it overrules $LANG, and
4079 * gtk_set_locale() calls setlocale() again. gnome_init()
4080 * sets $LC_CTYPE to "en_US" (that's a bug!). */
4081 if (what != VIM_LC_MESSAGES)
4082 vim_setenv((char_u *)"LC_CTYPE", name);
4083 # ifdef FEAT_GUI_GTK
4084 /* Let GTK know what locale we're using. Not sure this is
4085 * really needed... */
4086 if (gui.in_use)
4087 (void)gtk_set_locale();
4088 # endif
4091 # ifdef FEAT_EVAL
4092 /* Set v:lang, v:lc_time and v:ctype to the final result. */
4093 set_lang_var();
4094 # endif
4099 # if defined(FEAT_CMDL_COMPL) || defined(PROTO)
4101 * Function given to ExpandGeneric() to obtain the possible arguments of the
4102 * ":language" command.
4104 /*ARGSUSED*/
4105 char_u *
4106 get_lang_arg(xp, idx)
4107 expand_T *xp;
4108 int idx;
4110 if (idx == 0)
4111 return (char_u *)"messages";
4112 if (idx == 1)
4113 return (char_u *)"ctype";
4114 if (idx == 2)
4115 return (char_u *)"time";
4116 return NULL;
4118 # endif
4120 #endif