1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * scriptfile.c: functions for dealing with the runtime directories/files 12 */ 13 14 #include "vim.h" 15 16 #if defined(FEAT_EVAL) || defined(PROTO) 17 // The names of packages that once were loaded are remembered. 18 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 19 #endif 20 21 /* 22 * ":runtime [what] {name}" 23 */ 24 void 25 ex_runtime(exarg_T *eap) 26 { 27 char_u *arg = eap->arg; 28 char_u *p = skiptowhite(arg); 29 int len = (int)(p - arg); 30 int flags = eap->forceit ? DIP_ALL : 0; 31 32 if (STRNCMP(arg, "START", len) == 0) 33 { 34 flags += DIP_START + DIP_NORTP; 35 arg = skipwhite(arg + len); 36 } 37 else if (STRNCMP(arg, "OPT", len) == 0) 38 { 39 flags += DIP_OPT + DIP_NORTP; 40 arg = skipwhite(arg + len); 41 } 42 else if (STRNCMP(arg, "PACK", len) == 0) 43 { 44 flags += DIP_START + DIP_OPT + DIP_NORTP; 45 arg = skipwhite(arg + len); 46 } 47 else if (STRNCMP(arg, "ALL", len) == 0) 48 { 49 flags += DIP_START + DIP_OPT; 50 arg = skipwhite(arg + len); 51 } 52 53 source_runtime(arg, flags); 54 } 55 56 static void 57 source_callback(char_u *fname, void *cookie UNUSED) 58 { 59 (void)do_source(fname, FALSE, DOSO_NONE); 60 } 61 62 /* 63 * Find the file "name" in all directories in "path" and invoke 64 * "callback(fname, cookie)". 65 * "name" can contain wildcards. 66 * When "flags" has DIP_ALL: source all files, otherwise only the first one. 67 * When "flags" has DIP_DIR: find directories instead of files. 68 * When "flags" has DIP_ERR: give an error message if there is no match. 69 * 70 * return FAIL when no file could be sourced, OK otherwise. 71 */ 72 int 73 do_in_path( 74 char_u *path, 75 char_u *name, 76 int flags, 77 void (*callback)(char_u *fname, void *ck), 78 void *cookie) 79 { 80 char_u *rtp; 81 char_u *np; 82 char_u *buf; 83 char_u *rtp_copy; 84 char_u *tail; 85 int num_files; 86 char_u **files; 87 int i; 88 int did_one = FALSE; 89 #ifdef AMIGA 90 struct Process *proc = (struct Process *)FindTask(0L); 91 APTR save_winptr = proc->pr_WindowPtr; 92 93 // Avoid a requester here for a volume that doesn't exist. 94 proc->pr_WindowPtr = (APTR)-1L; 95 #endif 96 97 // Make a copy of 'runtimepath'. Invoking the callback may change the 98 // value. 99 rtp_copy = vim_strsave(path); 100 buf = alloc(MAXPATHL); 101 if (buf != NULL && rtp_copy != NULL) 102 { 103 if (p_verbose > 1 && name != NULL) 104 { 105 verbose_enter(); 106 smsg(_("Searching for \"%s\" in \"%s\""), 107 (char *)name, (char *)path); 108 verbose_leave(); 109 } 110 111 // Loop over all entries in 'runtimepath'. 112 rtp = rtp_copy; 113 while (*rtp != NUL && ((flags & DIP_ALL) || !did_one)) 114 { 115 size_t buflen; 116 117 // Copy the path from 'runtimepath' to buf[]. 118 copy_option_part(&rtp, buf, MAXPATHL, ","); 119 buflen = STRLEN(buf); 120 121 // Skip after or non-after directories. 122 if (flags & (DIP_NOAFTER | DIP_AFTER)) 123 { 124 int is_after = buflen >= 5 125 && STRCMP(buf + buflen - 5, "after") == 0; 126 127 if ((is_after && (flags & DIP_NOAFTER)) 128 || (!is_after && (flags & DIP_AFTER))) 129 continue; 130 } 131 132 if (name == NULL) 133 { 134 (*callback)(buf, (void *) &cookie); 135 if (!did_one) 136 did_one = (cookie == NULL); 137 } 138 else if (buflen + STRLEN(name) + 2 < MAXPATHL) 139 { 140 add_pathsep(buf); 141 tail = buf + STRLEN(buf); 142 143 // Loop over all patterns in "name" 144 np = name; 145 while (*np != NUL && ((flags & DIP_ALL) || !did_one)) 146 { 147 // Append the pattern from "name" to buf[]. 148 copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)), 149 "\t "); 150 151 if (p_verbose > 2) 152 { 153 verbose_enter(); 154 smsg(_("Searching for \"%s\""), buf); 155 verbose_leave(); 156 } 157 158 // Expand wildcards, invoke the callback for each match. 159 if (gen_expand_wildcards(1, &buf, &num_files, &files, 160 (flags & DIP_DIR) ? EW_DIR : EW_FILE) == OK) 161 { 162 for (i = 0; i < num_files; ++i) 163 { 164 (*callback)(files[i], cookie); 165 did_one = TRUE; 166 if (!(flags & DIP_ALL)) 167 break; 168 } 169 FreeWild(num_files, files); 170 } 171 } 172 } 173 } 174 } 175 vim_free(buf); 176 vim_free(rtp_copy); 177 if (!did_one && name != NULL) 178 { 179 char *basepath = path == p_rtp ? "runtimepath" : "packpath"; 180 181 if (flags & DIP_ERR) 182 semsg(_(e_dirnotf), basepath, name); 183 else if (p_verbose > 0) 184 { 185 verbose_enter(); 186 smsg(_("not found in '%s': \"%s\""), basepath, name); 187 verbose_leave(); 188 } 189 } 190 191 #ifdef AMIGA 192 proc->pr_WindowPtr = save_winptr; 193 #endif 194 195 return did_one ? OK : FAIL; 196 } 197 198 /* 199 * Find "name" in "path". When found, invoke the callback function for 200 * it: callback(fname, "cookie") 201 * When "flags" has DIP_ALL repeat for all matches, otherwise only the first 202 * one is used. 203 * Returns OK when at least one match found, FAIL otherwise. 204 * 205 * If "name" is NULL calls callback for each entry in "path". Cookie is 206 * passed by reference in this case, setting it to NULL indicates that callback 207 * has done its job. 208 */ 209 static int 210 do_in_path_and_pp( 211 char_u *path, 212 char_u *name, 213 int flags, 214 void (*callback)(char_u *fname, void *ck), 215 void *cookie) 216 { 217 int done = FAIL; 218 char_u *s; 219 int len; 220 char *start_dir = "pack/*/start/*/%s"; 221 char *opt_dir = "pack/*/opt/*/%s"; 222 223 if ((flags & DIP_NORTP) == 0) 224 done = do_in_path(path, name, flags, callback, cookie); 225 226 if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) 227 { 228 len = (int)(STRLEN(start_dir) + STRLEN(name)); 229 s = alloc(len); 230 if (s == NULL) 231 return FAIL; 232 vim_snprintf((char *)s, len, start_dir, name); 233 done = do_in_path(p_pp, s, flags, callback, cookie); 234 vim_free(s); 235 } 236 237 if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_OPT)) 238 { 239 len = (int)(STRLEN(opt_dir) + STRLEN(name)); 240 s = alloc(len); 241 if (s == NULL) 242 return FAIL; 243 vim_snprintf((char *)s, len, opt_dir, name); 244 done = do_in_path(p_pp, s, flags, callback, cookie); 245 vim_free(s); 246 } 247 248 return done; 249 } 250 251 /* 252 * Just like do_in_path_and_pp(), using 'runtimepath' for "path". 253 */ 254 int 255 do_in_runtimepath( 256 char_u *name, 257 int flags, 258 void (*callback)(char_u *fname, void *ck), 259 void *cookie) 260 { 261 return do_in_path_and_pp(p_rtp, name, flags, callback, cookie); 262 } 263 264 /* 265 * Source the file "name" from all directories in 'runtimepath'. 266 * "name" can contain wildcards. 267 * When "flags" has DIP_ALL: source all files, otherwise only the first one. 268 * 269 * return FAIL when no file could be sourced, OK otherwise. 270 */ 271 int 272 source_runtime(char_u *name, int flags) 273 { 274 return source_in_path(p_rtp, name, flags); 275 } 276 277 /* 278 * Just like source_runtime(), but use "path" instead of 'runtimepath'. 279 */ 280 int 281 source_in_path(char_u *path, char_u *name, int flags) 282 { 283 return do_in_path_and_pp(path, name, flags, source_callback, NULL); 284 } 285 286 287 #if defined(FEAT_EVAL) || defined(PROTO) 288 289 /* 290 * Expand wildcards in "pat" and invoke do_source() for each match. 291 */ 292 static void 293 source_all_matches(char_u *pat) 294 { 295 int num_files; 296 char_u **files; 297 int i; 298 299 if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK) 300 { 301 for (i = 0; i < num_files; ++i) 302 (void)do_source(files[i], FALSE, DOSO_NONE); 303 FreeWild(num_files, files); 304 } 305 } 306 307 /* 308 * Add the package directory to 'runtimepath'. 309 */ 310 static int 311 add_pack_dir_to_rtp(char_u *fname) 312 { 313 char_u *p4, *p3, *p2, *p1, *p; 314 char_u *entry; 315 char_u *insp = NULL; 316 int c; 317 char_u *new_rtp; 318 int keep; 319 size_t oldlen; 320 size_t addlen; 321 size_t new_rtp_len; 322 char_u *afterdir = NULL; 323 size_t afterlen = 0; 324 char_u *after_insp = NULL; 325 char_u *ffname = NULL; 326 size_t fname_len; 327 char_u *buf = NULL; 328 char_u *rtp_ffname; 329 int match; 330 int retval = FAIL; 331 332 p4 = p3 = p2 = p1 = get_past_head(fname); 333 for (p = p1; *p; MB_PTR_ADV(p)) 334 if (vim_ispathsep_nocolon(*p)) 335 { 336 p4 = p3; p3 = p2; p2 = p1; p1 = p; 337 } 338 339 // now we have: 340 // rtp/pack/name/start/name 341 // p4 p3 p2 p1 342 // 343 // find the part up to "pack" in 'runtimepath' 344 c = *++p4; // append pathsep in order to expand symlink 345 *p4 = NUL; 346 ffname = fix_fname(fname); 347 *p4 = c; 348 if (ffname == NULL) 349 return FAIL; 350 351 // Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. 352 // Also stop at the first "after" directory. 353 fname_len = STRLEN(ffname); 354 buf = alloc(MAXPATHL); 355 if (buf == NULL) 356 goto theend; 357 for (entry = p_rtp; *entry != NUL; ) 358 { 359 char_u *cur_entry = entry; 360 361 copy_option_part(&entry, buf, MAXPATHL, ","); 362 if (insp == NULL) 363 { 364 add_pathsep(buf); 365 rtp_ffname = fix_fname(buf); 366 if (rtp_ffname == NULL) 367 goto theend; 368 match = vim_fnamencmp(rtp_ffname, ffname, fname_len) == 0; 369 vim_free(rtp_ffname); 370 if (match) 371 // Insert "ffname" after this entry (and comma). 372 insp = entry; 373 } 374 375 if ((p = (char_u *)strstr((char *)buf, "after")) != NULL 376 && p > buf 377 && vim_ispathsep(p[-1]) 378 && (vim_ispathsep(p[5]) || p[5] == NUL || p[5] == ',')) 379 { 380 if (insp == NULL) 381 // Did not find "ffname" before the first "after" directory, 382 // insert it before this entry. 383 insp = cur_entry; 384 after_insp = cur_entry; 385 break; 386 } 387 } 388 389 if (insp == NULL) 390 // Both "fname" and "after" not found, append at the end. 391 insp = p_rtp + STRLEN(p_rtp); 392 393 // check if rtp/pack/name/start/name/after exists 394 afterdir = concat_fnames(fname, (char_u *)"after", TRUE); 395 if (afterdir != NULL && mch_isdir(afterdir)) 396 afterlen = STRLEN(afterdir) + 1; // add one for comma 397 398 oldlen = STRLEN(p_rtp); 399 addlen = STRLEN(fname) + 1; // add one for comma 400 new_rtp = alloc(oldlen + addlen + afterlen + 1); // add one for NUL 401 if (new_rtp == NULL) 402 goto theend; 403 404 // We now have 'rtp' parts: {keep}{keep_after}{rest}. 405 // Create new_rtp, first: {keep},{fname} 406 keep = (int)(insp - p_rtp); 407 mch_memmove(new_rtp, p_rtp, keep); 408 new_rtp_len = keep; 409 if (*insp == NUL) 410 new_rtp[new_rtp_len++] = ','; // add comma before 411 mch_memmove(new_rtp + new_rtp_len, fname, addlen - 1); 412 new_rtp_len += addlen - 1; 413 if (*insp != NUL) 414 new_rtp[new_rtp_len++] = ','; // add comma after 415 416 if (afterlen > 0 && after_insp != NULL) 417 { 418 int keep_after = (int)(after_insp - p_rtp); 419 420 // Add to new_rtp: {keep},{fname}{keep_after},{afterdir} 421 mch_memmove(new_rtp + new_rtp_len, p_rtp + keep, 422 keep_after - keep); 423 new_rtp_len += keep_after - keep; 424 mch_memmove(new_rtp + new_rtp_len, afterdir, afterlen - 1); 425 new_rtp_len += afterlen - 1; 426 new_rtp[new_rtp_len++] = ','; 427 keep = keep_after; 428 } 429 430 if (p_rtp[keep] != NUL) 431 // Append rest: {keep},{fname}{keep_after},{afterdir}{rest} 432 mch_memmove(new_rtp + new_rtp_len, p_rtp + keep, oldlen - keep + 1); 433 else 434 new_rtp[new_rtp_len] = NUL; 435 436 if (afterlen > 0 && after_insp == NULL) 437 { 438 // Append afterdir when "after" was not found: 439 // {keep},{fname}{rest},{afterdir} 440 STRCAT(new_rtp, ","); 441 STRCAT(new_rtp, afterdir); 442 } 443 444 set_option_value((char_u *)"rtp", 0L, new_rtp, 0); 445 vim_free(new_rtp); 446 retval = OK; 447 448 theend: 449 vim_free(buf); 450 vim_free(ffname); 451 vim_free(afterdir); 452 return retval; 453 } 454 455 /* 456 * Load scripts in "plugin" and "ftdetect" directories of the package. 457 */ 458 static int 459 load_pack_plugin(char_u *fname) 460 { 461 static char *plugpat = "%s/plugin/**/*.vim"; 462 static char *ftpat = "%s/ftdetect/*.vim"; 463 int len; 464 char_u *ffname = fix_fname(fname); 465 char_u *pat = NULL; 466 int retval = FAIL; 467 468 if (ffname == NULL) 469 return FAIL; 470 len = (int)STRLEN(ffname) + (int)STRLEN(ftpat); 471 pat = alloc(len); 472 if (pat == NULL) 473 goto theend; 474 vim_snprintf((char *)pat, len, plugpat, ffname); 475 source_all_matches(pat); 476 477 { 478 char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes"); 479 480 // If runtime/filetype.vim wasn't loaded yet, the scripts will be 481 // found when it loads. 482 if (cmd != NULL && eval_to_number(cmd) > 0) 483 { 484 do_cmdline_cmd((char_u *)"augroup filetypedetect"); 485 vim_snprintf((char *)pat, len, ftpat, ffname); 486 source_all_matches(pat); 487 do_cmdline_cmd((char_u *)"augroup END"); 488 } 489 vim_free(cmd); 490 } 491 vim_free(pat); 492 retval = OK; 493 494 theend: 495 vim_free(ffname); 496 return retval; 497 } 498 499 // used for "cookie" of add_pack_plugin() 500 static int APP_ADD_DIR; 501 static int APP_LOAD; 502 static int APP_BOTH; 503 504 static void 505 add_pack_plugin(char_u *fname, void *cookie) 506 { 507 if (cookie != &APP_LOAD) 508 { 509 char_u *buf = alloc(MAXPATHL); 510 char_u *p; 511 int found = FALSE; 512 513 if (buf == NULL) 514 return; 515 p = p_rtp; 516 while (*p != NUL) 517 { 518 copy_option_part(&p, buf, MAXPATHL, ","); 519 if (pathcmp((char *)buf, (char *)fname, -1) == 0) 520 { 521 found = TRUE; 522 break; 523 } 524 } 525 vim_free(buf); 526 if (!found) 527 // directory is not yet in 'runtimepath', add it 528 if (add_pack_dir_to_rtp(fname) == FAIL) 529 return; 530 } 531 532 if (cookie != &APP_ADD_DIR) 533 load_pack_plugin(fname); 534 } 535 536 /* 537 * Add all packages in the "start" directory to 'runtimepath'. 538 */ 539 void 540 add_pack_start_dirs(void) 541 { 542 do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, 543 add_pack_plugin, &APP_ADD_DIR); 544 } 545 546 /* 547 * Load plugins from all packages in the "start" directory. 548 */ 549 void 550 load_start_packages(void) 551 { 552 did_source_packages = TRUE; 553 do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, 554 add_pack_plugin, &APP_LOAD); 555 } 556 557 /* 558 * ":packloadall" 559 * Find plugins in the package directories and source them. 560 */ 561 void 562 ex_packloadall(exarg_T *eap) 563 { 564 if (!did_source_packages || eap->forceit) 565 { 566 // First do a round to add all directories to 'runtimepath', then load 567 // the plugins. This allows for plugins to use an autoload directory 568 // of another plugin. 569 add_pack_start_dirs(); 570 load_start_packages(); 571 } 572 } 573 574 /* 575 * ":packadd[!] {name}" 576 */ 577 void 578 ex_packadd(exarg_T *eap) 579 { 580 static char *plugpat = "pack/*/%s/%s"; 581 int len; 582 char *pat; 583 int round; 584 int res = OK; 585 586 // Round 1: use "start", round 2: use "opt". 587 for (round = 1; round <= 2; ++round) 588 { 589 // Only look under "start" when loading packages wasn't done yet. 590 if (round == 1 && did_source_packages) 591 continue; 592 593 len = (int)STRLEN(plugpat) + (int)STRLEN(eap->arg) + 5; 594 pat = alloc(len); 595 if (pat == NULL) 596 return; 597 vim_snprintf(pat, len, plugpat, round == 1 ? "start" : "opt", eap->arg); 598 // The first round don't give a "not found" error, in the second round 599 // only when nothing was found in the first round. 600 res = do_in_path(p_pp, (char_u *)pat, 601 DIP_ALL + DIP_DIR + (round == 2 && res == FAIL ? DIP_ERR : 0), 602 add_pack_plugin, eap->forceit ? &APP_ADD_DIR : &APP_BOTH); 603 vim_free(pat); 604 } 605 } 606 #endif 607 608 /* 609 * Expand color scheme, compiler or filetype names. 610 * Search from 'runtimepath': 611 * 'runtimepath'/{dirnames}/{pat}.vim 612 * When "flags" has DIP_START: search also from 'start' of 'packpath': 613 * 'packpath'/pack/ * /start/ * /{dirnames}/{pat}.vim 614 * When "flags" has DIP_OPT: search also from 'opt' of 'packpath': 615 * 'packpath'/pack/ * /opt/ * /{dirnames}/{pat}.vim 616 * "dirnames" is an array with one or more directory names. 617 */ 618 int 619 ExpandRTDir( 620 char_u *pat, 621 int flags, 622 int *num_file, 623 char_u ***file, 624 char *dirnames[]) 625 { 626 char_u *s; 627 char_u *e; 628 char_u *match; 629 garray_T ga; 630 int i; 631 int pat_len; 632 633 *num_file = 0; 634 *file = NULL; 635 pat_len = (int)STRLEN(pat); 636 ga_init2(&ga, (int)sizeof(char *), 10); 637 638 for (i = 0; dirnames[i] != NULL; ++i) 639 { 640 s = alloc(STRLEN(dirnames[i]) + pat_len + 7); 641 if (s == NULL) 642 { 643 ga_clear_strings(&ga); 644 return FAIL; 645 } 646 sprintf((char *)s, "%s/%s*.vim", dirnames[i], pat); 647 globpath(p_rtp, s, &ga, 0); 648 vim_free(s); 649 } 650 651 if (flags & DIP_START) { 652 for (i = 0; dirnames[i] != NULL; ++i) 653 { 654 s = alloc(STRLEN(dirnames[i]) + pat_len + 22); 655 if (s == NULL) 656 { 657 ga_clear_strings(&ga); 658 return FAIL; 659 } 660 sprintf((char *)s, "pack/*/start/*/%s/%s*.vim", dirnames[i], pat); 661 globpath(p_pp, s, &ga, 0); 662 vim_free(s); 663 } 664 } 665 666 if (flags & DIP_OPT) { 667 for (i = 0; dirnames[i] != NULL; ++i) 668 { 669 s = alloc(STRLEN(dirnames[i]) + pat_len + 20); 670 if (s == NULL) 671 { 672 ga_clear_strings(&ga); 673 return FAIL; 674 } 675 sprintf((char *)s, "pack/*/opt/*/%s/%s*.vim", dirnames[i], pat); 676 globpath(p_pp, s, &ga, 0); 677 vim_free(s); 678 } 679 } 680 681 for (i = 0; i < ga.ga_len; ++i) 682 { 683 match = ((char_u **)ga.ga_data)[i]; 684 s = match; 685 e = s + STRLEN(s); 686 if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0) 687 { 688 e -= 4; 689 for (s = e; s > match; MB_PTR_BACK(match, s)) 690 if (s < match || vim_ispathsep(*s)) 691 break; 692 ++s; 693 *e = NUL; 694 mch_memmove(match, s, e - s + 1); 695 } 696 } 697 698 if (ga.ga_len == 0) 699 return FAIL; 700 701 // Sort and remove duplicates which can happen when specifying multiple 702 // directories in dirnames. 703 remove_duplicates(&ga); 704 705 *file = ga.ga_data; 706 *num_file = ga.ga_len; 707 return OK; 708 } 709 710 /* 711 * Expand loadplugin names: 712 * 'packpath'/pack/ * /opt/{pat} 713 */ 714 int 715 ExpandPackAddDir( 716 char_u *pat, 717 int *num_file, 718 char_u ***file) 719 { 720 char_u *s; 721 char_u *e; 722 char_u *match; 723 garray_T ga; 724 int i; 725 int pat_len; 726 727 *num_file = 0; 728 *file = NULL; 729 pat_len = (int)STRLEN(pat); 730 ga_init2(&ga, (int)sizeof(char *), 10); 731 732 s = alloc(pat_len + 26); 733 if (s == NULL) 734 { 735 ga_clear_strings(&ga); 736 return FAIL; 737 } 738 sprintf((char *)s, "pack/*/opt/%s*", pat); 739 globpath(p_pp, s, &ga, 0); 740 vim_free(s); 741 742 for (i = 0; i < ga.ga_len; ++i) 743 { 744 match = ((char_u **)ga.ga_data)[i]; 745 s = gettail(match); 746 e = s + STRLEN(s); 747 mch_memmove(match, s, e - s + 1); 748 } 749 750 if (ga.ga_len == 0) 751 return FAIL; 752 753 // Sort and remove duplicates which can happen when specifying multiple 754 // directories in dirnames. 755 remove_duplicates(&ga); 756 757 *file = ga.ga_data; 758 *num_file = ga.ga_len; 759 return OK; 760 } 761 762 static void 763 cmd_source(char_u *fname, exarg_T *eap) 764 { 765 if (*fname == NUL) 766 emsg(_(e_argreq)); 767 768 else if (eap != NULL && eap->forceit) 769 // ":source!": read Normal mode commands 770 // Need to execute the commands directly. This is required at least 771 // for: 772 // - ":g" command busy 773 // - after ":argdo", ":windo" or ":bufdo" 774 // - another command follows 775 // - inside a loop 776 openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL 777 #ifdef FEAT_EVAL 778 || eap->cstack->cs_idx >= 0 779 #endif 780 ); 781 782 // ":source" read ex commands 783 else if (do_source(fname, FALSE, DOSO_NONE) == FAIL) 784 semsg(_(e_notopen), fname); 785 } 786 787 /* 788 * ":source {fname}" 789 */ 790 void 791 ex_source(exarg_T *eap) 792 { 793 #ifdef FEAT_BROWSE 794 if (cmdmod.browse) 795 { 796 char_u *fname = NULL; 797 798 fname = do_browse(0, (char_u *)_("Source Vim script"), eap->arg, 799 NULL, NULL, 800 (char_u *)_(BROWSE_FILTER_MACROS), NULL); 801 if (fname != NULL) 802 { 803 cmd_source(fname, eap); 804 vim_free(fname); 805 } 806 } 807 else 808 #endif 809 cmd_source(eap->arg, eap); 810 } 811 812 #if defined(FEAT_EVAL) || defined(PROTO) 813 /* 814 * ":options" 815 */ 816 void 817 ex_options( 818 exarg_T *eap UNUSED) 819 { 820 vim_setenv((char_u *)"OPTWIN_CMD", 821 (char_u *)(cmdmod.tab ? "tab" 822 : (cmdmod.split & WSP_VERT) ? "vert" : "")); 823 cmd_source((char_u *)SYS_OPTWIN_FILE, NULL); 824 } 825 #endif 826 827 /* 828 * ":source" and associated commands. 829 */ 830 /* 831 * Structure used to store info for each sourced file. 832 * It is shared between do_source() and getsourceline(). 833 * This is required, because it needs to be handed to do_cmdline() and 834 * sourcing can be done recursively. 835 */ 836 struct source_cookie 837 { 838 FILE *fp; // opened file for sourcing 839 char_u *nextline; // if not NULL: line that was read ahead 840 linenr_T sourcing_lnum; // line number of the source file 841 int finished; // ":finish" used 842 #ifdef USE_CRNL 843 int fileformat; // EOL_UNKNOWN, EOL_UNIX or EOL_DOS 844 int error; // TRUE if LF found after CR-LF 845 #endif 846 #ifdef FEAT_EVAL 847 linenr_T breakpoint; // next line with breakpoint or zero 848 char_u *fname; // name of sourced file 849 int dbg_tick; // debug_tick when breakpoint was set 850 int level; // top nesting level of sourced file 851 #endif 852 vimconv_T conv; // type of conversion 853 }; 854 855 #ifdef FEAT_EVAL 856 /* 857 * Return the address holding the next breakpoint line for a source cookie. 858 */ 859 linenr_T * 860 source_breakpoint(void *cookie) 861 { 862 return &((struct source_cookie *)cookie)->breakpoint; 863 } 864 865 /* 866 * Return the address holding the debug tick for a source cookie. 867 */ 868 int * 869 source_dbg_tick(void *cookie) 870 { 871 return &((struct source_cookie *)cookie)->dbg_tick; 872 } 873 874 /* 875 * Return the nesting level for a source cookie. 876 */ 877 int 878 source_level(void *cookie) 879 { 880 return ((struct source_cookie *)cookie)->level; 881 } 882 #endif 883 884 #if (defined(MSWIN) && defined(FEAT_CSCOPE)) || defined(HAVE_FD_CLOEXEC) 885 # define USE_FOPEN_NOINH 886 /* 887 * Special function to open a file without handle inheritance. 888 * When possible the handle is closed on exec(). 889 */ 890 static FILE * 891 fopen_noinh_readbin(char *filename) 892 { 893 # ifdef MSWIN 894 int fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0); 895 # else 896 int fd_tmp = mch_open(filename, O_RDONLY, 0); 897 # endif 898 899 if (fd_tmp == -1) 900 return NULL; 901 902 # ifdef HAVE_FD_CLOEXEC 903 { 904 int fdflags = fcntl(fd_tmp, F_GETFD); 905 if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) 906 (void)fcntl(fd_tmp, F_SETFD, fdflags | FD_CLOEXEC); 907 } 908 # endif 909 910 return fdopen(fd_tmp, READBIN); 911 } 912 #endif 913 914 /* 915 * do_source: Read the file "fname" and execute its lines as EX commands. 916 * 917 * This function may be called recursively! 918 * 919 * return FAIL if file could not be opened, OK otherwise 920 */ 921 int 922 do_source( 923 char_u *fname, 924 int check_other, // check for .vimrc and _vimrc 925 int is_vimrc) // DOSO_ value 926 { 927 struct source_cookie cookie; 928 char_u *save_sourcing_name; 929 linenr_T save_sourcing_lnum; 930 char_u *p; 931 char_u *fname_exp; 932 char_u *firstline = NULL; 933 int retval = FAIL; 934 #ifdef FEAT_EVAL 935 sctx_T save_current_sctx; 936 static scid_T last_current_SID = 0; 937 static int last_current_SID_seq = 0; 938 funccal_entry_T funccalp_entry; 939 int save_debug_break_level = debug_break_level; 940 scriptitem_T *si = NULL; 941 # ifdef UNIX 942 stat_T st; 943 int stat_ok; 944 # endif 945 #endif 946 #ifdef STARTUPTIME 947 struct timeval tv_rel; 948 struct timeval tv_start; 949 #endif 950 #ifdef FEAT_PROFILE 951 proftime_T wait_start; 952 #endif 953 int trigger_source_post = FALSE; 954 955 p = expand_env_save(fname); 956 if (p == NULL) 957 return retval; 958 fname_exp = fix_fname(p); 959 vim_free(p); 960 if (fname_exp == NULL) 961 return retval; 962 if (mch_isdir(fname_exp)) 963 { 964 smsg(_("Cannot source a directory: \"%s\""), fname); 965 goto theend; 966 } 967 968 // Apply SourceCmd autocommands, they should get the file and source it. 969 if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL) 970 && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp, 971 FALSE, curbuf)) 972 { 973 #ifdef FEAT_EVAL 974 retval = aborting() ? FAIL : OK; 975 #else 976 retval = OK; 977 #endif 978 if (retval == OK) 979 // Apply SourcePost autocommands. 980 apply_autocmds(EVENT_SOURCEPOST, fname_exp, fname_exp, 981 FALSE, curbuf); 982 goto theend; 983 } 984 985 // Apply SourcePre autocommands, they may get the file. 986 apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf); 987 988 #ifdef USE_FOPEN_NOINH 989 cookie.fp = fopen_noinh_readbin((char *)fname_exp); 990 #else 991 cookie.fp = mch_fopen((char *)fname_exp, READBIN); 992 #endif 993 if (cookie.fp == NULL && check_other) 994 { 995 // Try again, replacing file name ".vimrc" by "_vimrc" or vice versa, 996 // and ".exrc" by "_exrc" or vice versa. 997 p = gettail(fname_exp); 998 if ((*p == '.' || *p == '_') 999 && (STRICMP(p + 1, "vimrc") == 0 1000 || STRICMP(p + 1, "gvimrc") == 0 1001 || STRICMP(p + 1, "exrc") == 0)) 1002 { 1003 if (*p == '_') 1004 *p = '.'; 1005 else 1006 *p = '_'; 1007 #ifdef USE_FOPEN_NOINH 1008 cookie.fp = fopen_noinh_readbin((char *)fname_exp); 1009 #else 1010 cookie.fp = mch_fopen((char *)fname_exp, READBIN); 1011 #endif 1012 } 1013 } 1014 1015 if (cookie.fp == NULL) 1016 { 1017 if (p_verbose > 0) 1018 { 1019 verbose_enter(); 1020 if (sourcing_name == NULL) 1021 smsg(_("could not source \"%s\""), fname); 1022 else 1023 smsg(_("line %ld: could not source \"%s\""), 1024 sourcing_lnum, fname); 1025 verbose_leave(); 1026 } 1027 goto theend; 1028 } 1029 1030 // The file exists. 1031 // - In verbose mode, give a message. 1032 // - For a vimrc file, may want to set 'compatible', call vimrc_found(). 1033 if (p_verbose > 1) 1034 { 1035 verbose_enter(); 1036 if (sourcing_name == NULL) 1037 smsg(_("sourcing \"%s\""), fname); 1038 else 1039 smsg(_("line %ld: sourcing \"%s\""), 1040 sourcing_lnum, fname); 1041 verbose_leave(); 1042 } 1043 if (is_vimrc == DOSO_VIMRC) 1044 vimrc_found(fname_exp, (char_u *)"MYVIMRC"); 1045 else if (is_vimrc == DOSO_GVIMRC) 1046 vimrc_found(fname_exp, (char_u *)"MYGVIMRC"); 1047 1048 #ifdef USE_CRNL 1049 // If no automatic file format: Set default to CR-NL. 1050 if (*p_ffs == NUL) 1051 cookie.fileformat = EOL_DOS; 1052 else 1053 cookie.fileformat = EOL_UNKNOWN; 1054 cookie.error = FALSE; 1055 #endif 1056 1057 cookie.nextline = NULL; 1058 cookie.sourcing_lnum = 0; 1059 cookie.finished = FALSE; 1060 1061 #ifdef FEAT_EVAL 1062 // Check if this script has a breakpoint. 1063 cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0); 1064 cookie.fname = fname_exp; 1065 cookie.dbg_tick = debug_tick; 1066 1067 cookie.level = ex_nesting_level; 1068 #endif 1069 1070 // Keep the sourcing name/lnum, for recursive calls. 1071 save_sourcing_name = sourcing_name; 1072 sourcing_name = fname_exp; 1073 save_sourcing_lnum = sourcing_lnum; 1074 sourcing_lnum = 0; 1075 1076 #ifdef STARTUPTIME 1077 if (time_fd != NULL) 1078 time_push(&tv_rel, &tv_start); 1079 #endif 1080 1081 #ifdef FEAT_EVAL 1082 # ifdef FEAT_PROFILE 1083 if (do_profiling == PROF_YES) 1084 prof_child_enter(&wait_start); // entering a child now 1085 # endif 1086 1087 // Don't use local function variables, if called from a function. 1088 // Also starts profiling timer for nested script. 1089 save_funccal(&funccalp_entry); 1090 1091 save_current_sctx = current_sctx; 1092 current_sctx.sc_lnum = 0; 1093 current_sctx.sc_version = 1; 1094 1095 // Check if this script was sourced before to finds its SID. 1096 // If it's new, generate a new SID. 1097 // Always use a new sequence number. 1098 current_sctx.sc_seq = ++last_current_SID_seq; 1099 # ifdef UNIX 1100 stat_ok = (mch_stat((char *)fname_exp, &st) >= 0); 1101 # endif 1102 for (current_sctx.sc_sid = script_items.ga_len; current_sctx.sc_sid > 0; 1103 --current_sctx.sc_sid) 1104 { 1105 si = &SCRIPT_ITEM(current_sctx.sc_sid); 1106 if (si->sn_name != NULL 1107 && ( 1108 # ifdef UNIX 1109 // Compare dev/ino when possible, it catches symbolic 1110 // links. Also compare file names, the inode may change 1111 // when the file was edited. 1112 ((stat_ok && si->sn_dev_valid) 1113 && (si->sn_dev == st.st_dev 1114 && si->sn_ino == st.st_ino)) || 1115 # endif 1116 fnamecmp(si->sn_name, fname_exp) == 0)) 1117 break; 1118 } 1119 if (current_sctx.sc_sid == 0) 1120 { 1121 current_sctx.sc_sid = ++last_current_SID; 1122 if (ga_grow(&script_items, 1123 (int)(current_sctx.sc_sid - script_items.ga_len)) == FAIL) 1124 goto almosttheend; 1125 while (script_items.ga_len < current_sctx.sc_sid) 1126 { 1127 ++script_items.ga_len; 1128 SCRIPT_ITEM(script_items.ga_len).sn_name = NULL; 1129 # ifdef FEAT_PROFILE 1130 SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE; 1131 # endif 1132 } 1133 si = &SCRIPT_ITEM(current_sctx.sc_sid); 1134 si->sn_name = fname_exp; 1135 fname_exp = vim_strsave(si->sn_name); // used for autocmd 1136 # ifdef UNIX 1137 if (stat_ok) 1138 { 1139 si->sn_dev_valid = TRUE; 1140 si->sn_dev = st.st_dev; 1141 si->sn_ino = st.st_ino; 1142 } 1143 else 1144 si->sn_dev_valid = FALSE; 1145 # endif 1146 1147 // Allocate the local script variables to use for this script. 1148 new_script_vars(current_sctx.sc_sid); 1149 } 1150 1151 # ifdef FEAT_PROFILE 1152 if (do_profiling == PROF_YES) 1153 { 1154 int forceit; 1155 1156 // Check if we do profiling for this script. 1157 if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit)) 1158 { 1159 script_do_profile(si); 1160 si->sn_pr_force = forceit; 1161 } 1162 if (si->sn_prof_on) 1163 { 1164 ++si->sn_pr_count; 1165 profile_start(&si->sn_pr_start); 1166 profile_zero(&si->sn_pr_children); 1167 } 1168 } 1169 # endif 1170 #endif 1171 1172 cookie.conv.vc_type = CONV_NONE; // no conversion 1173 1174 // Read the first line so we can check for a UTF-8 BOM. 1175 firstline = getsourceline(0, (void *)&cookie, 0, TRUE); 1176 if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef 1177 && firstline[1] == 0xbb && firstline[2] == 0xbf) 1178 { 1179 // Found BOM; setup conversion, skip over BOM and recode the line. 1180 convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc); 1181 p = string_convert(&cookie.conv, firstline + 3, NULL); 1182 if (p == NULL) 1183 p = vim_strsave(firstline + 3); 1184 if (p != NULL) 1185 { 1186 vim_free(firstline); 1187 firstline = p; 1188 } 1189 } 1190 1191 // Call do_cmdline, which will call getsourceline() to get the lines. 1192 do_cmdline(firstline, getsourceline, (void *)&cookie, 1193 DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT); 1194 retval = OK; 1195 1196 #ifdef FEAT_PROFILE 1197 if (do_profiling == PROF_YES) 1198 { 1199 // Get "si" again, "script_items" may have been reallocated. 1200 si = &SCRIPT_ITEM(current_sctx.sc_sid); 1201 if (si->sn_prof_on) 1202 { 1203 profile_end(&si->sn_pr_start); 1204 profile_sub_wait(&wait_start, &si->sn_pr_start); 1205 profile_add(&si->sn_pr_total, &si->sn_pr_start); 1206 profile_self(&si->sn_pr_self, &si->sn_pr_start, 1207 &si->sn_pr_children); 1208 } 1209 } 1210 #endif 1211 1212 if (got_int) 1213 emsg(_(e_interr)); 1214 sourcing_name = save_sourcing_name; 1215 sourcing_lnum = save_sourcing_lnum; 1216 if (p_verbose > 1) 1217 { 1218 verbose_enter(); 1219 smsg(_("finished sourcing %s"), fname); 1220 if (sourcing_name != NULL) 1221 smsg(_("continuing in %s"), sourcing_name); 1222 verbose_leave(); 1223 } 1224 #ifdef STARTUPTIME 1225 if (time_fd != NULL) 1226 { 1227 vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname); 1228 time_msg((char *)IObuff, &tv_start); 1229 time_pop(&tv_rel); 1230 } 1231 #endif 1232 1233 if (!got_int) 1234 trigger_source_post = TRUE; 1235 1236 #ifdef FEAT_EVAL 1237 // After a "finish" in debug mode, need to break at first command of next 1238 // sourced file. 1239 if (save_debug_break_level > ex_nesting_level 1240 && debug_break_level == ex_nesting_level) 1241 ++debug_break_level; 1242 #endif 1243 1244 #ifdef FEAT_EVAL 1245 almosttheend: 1246 current_sctx = save_current_sctx; 1247 restore_funccal(); 1248 # ifdef FEAT_PROFILE 1249 if (do_profiling == PROF_YES) 1250 prof_child_exit(&wait_start); // leaving a child now 1251 # endif 1252 #endif 1253 fclose(cookie.fp); 1254 vim_free(cookie.nextline); 1255 vim_free(firstline); 1256 convert_setup(&cookie.conv, NULL, NULL); 1257 1258 if (trigger_source_post) 1259 apply_autocmds(EVENT_SOURCEPOST, fname_exp, fname_exp, FALSE, curbuf); 1260 1261 theend: 1262 vim_free(fname_exp); 1263 return retval; 1264 } 1265 1266 #if defined(FEAT_EVAL) || defined(PROTO) 1267 1268 /* 1269 * ":scriptnames" 1270 */ 1271 void 1272 ex_scriptnames(exarg_T *eap) 1273 { 1274 int i; 1275 1276 if (eap->addr_count > 0) 1277 { 1278 // :script {scriptId}: edit the script 1279 if (eap->line2 < 1 || eap->line2 > script_items.ga_len) 1280 emsg(_(e_invarg)); 1281 else 1282 { 1283 eap->arg = SCRIPT_ITEM(eap->line2).sn_name; 1284 do_exedit(eap, NULL); 1285 } 1286 return; 1287 } 1288 1289 for (i = 1; i <= script_items.ga_len && !got_int; ++i) 1290 if (SCRIPT_ITEM(i).sn_name != NULL) 1291 { 1292 home_replace(NULL, SCRIPT_ITEM(i).sn_name, 1293 NameBuff, MAXPATHL, TRUE); 1294 smsg("%3d: %s", i, NameBuff); 1295 } 1296 } 1297 1298 # if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) 1299 /* 1300 * Fix slashes in the list of script names for 'shellslash'. 1301 */ 1302 void 1303 scriptnames_slash_adjust(void) 1304 { 1305 int i; 1306 1307 for (i = 1; i <= script_items.ga_len; ++i) 1308 if (SCRIPT_ITEM(i).sn_name != NULL) 1309 slash_adjust(SCRIPT_ITEM(i).sn_name); 1310 } 1311 # endif 1312 1313 /* 1314 * Get a pointer to a script name. Used for ":verbose set". 1315 */ 1316 char_u * 1317 get_scriptname(scid_T id) 1318 { 1319 if (id == SID_MODELINE) 1320 return (char_u *)_("modeline"); 1321 if (id == SID_CMDARG) 1322 return (char_u *)_("--cmd argument"); 1323 if (id == SID_CARG) 1324 return (char_u *)_("-c argument"); 1325 if (id == SID_ENV) 1326 return (char_u *)_("environment variable"); 1327 if (id == SID_ERROR) 1328 return (char_u *)_("error handler"); 1329 return SCRIPT_ITEM(id).sn_name; 1330 } 1331 1332 # if defined(EXITFREE) || defined(PROTO) 1333 void 1334 free_scriptnames(void) 1335 { 1336 int i; 1337 1338 for (i = script_items.ga_len; i > 0; --i) 1339 vim_free(SCRIPT_ITEM(i).sn_name); 1340 ga_clear(&script_items); 1341 } 1342 1343 void 1344 free_autoload_scriptnames(void) 1345 { 1346 ga_clear_strings(&ga_loaded); 1347 } 1348 # endif 1349 1350 #endif 1351 1352 linenr_T 1353 get_sourced_lnum(char_u *(*fgetline)(int, void *, int, int), void *cookie) 1354 { 1355 return fgetline == getsourceline 1356 ? ((struct source_cookie *)cookie)->sourcing_lnum 1357 : sourcing_lnum; 1358 } 1359 1360 static char_u * 1361 get_one_sourceline(struct source_cookie *sp) 1362 { 1363 garray_T ga; 1364 int len; 1365 int c; 1366 char_u *buf; 1367 #ifdef USE_CRNL 1368 int has_cr; // CR-LF found 1369 #endif 1370 int have_read = FALSE; 1371 1372 // use a growarray to store the sourced line 1373 ga_init2(&ga, 1, 250); 1374 1375 // Loop until there is a finished line (or end-of-file). 1376 ++sp->sourcing_lnum; 1377 for (;;) 1378 { 1379 // make room to read at least 120 (more) characters 1380 if (ga_grow(&ga, 120) == FAIL) 1381 break; 1382 buf = (char_u *)ga.ga_data; 1383 1384 if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len, 1385 sp->fp) == NULL) 1386 break; 1387 len = ga.ga_len + (int)STRLEN(buf + ga.ga_len); 1388 #ifdef USE_CRNL 1389 // Ignore a trailing CTRL-Z, when in Dos mode. Only recognize the 1390 // CTRL-Z by its own, or after a NL. 1391 if ( (len == 1 || (len >= 2 && buf[len - 2] == '\n')) 1392 && sp->fileformat == EOL_DOS 1393 && buf[len - 1] == Ctrl_Z) 1394 { 1395 buf[len - 1] = NUL; 1396 break; 1397 } 1398 #endif 1399 1400 have_read = TRUE; 1401 ga.ga_len = len; 1402 1403 // If the line was longer than the buffer, read more. 1404 if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n') 1405 continue; 1406 1407 if (len >= 1 && buf[len - 1] == '\n') // remove trailing NL 1408 { 1409 #ifdef USE_CRNL 1410 has_cr = (len >= 2 && buf[len - 2] == '\r'); 1411 if (sp->fileformat == EOL_UNKNOWN) 1412 { 1413 if (has_cr) 1414 sp->fileformat = EOL_DOS; 1415 else 1416 sp->fileformat = EOL_UNIX; 1417 } 1418 1419 if (sp->fileformat == EOL_DOS) 1420 { 1421 if (has_cr) // replace trailing CR 1422 { 1423 buf[len - 2] = '\n'; 1424 --len; 1425 --ga.ga_len; 1426 } 1427 else // lines like ":map xx yy^M" will have failed 1428 { 1429 if (!sp->error) 1430 { 1431 msg_source(HL_ATTR(HLF_W)); 1432 emsg(_("W15: Warning: Wrong line separator, ^M may be missing")); 1433 } 1434 sp->error = TRUE; 1435 sp->fileformat = EOL_UNIX; 1436 } 1437 } 1438 #endif 1439 // The '\n' is escaped if there is an odd number of ^V's just 1440 // before it, first set "c" just before the 'V's and then check 1441 // len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo 1442 for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--) 1443 ; 1444 if ((len & 1) != (c & 1)) // escaped NL, read more 1445 { 1446 ++sp->sourcing_lnum; 1447 continue; 1448 } 1449 1450 buf[len - 1] = NUL; // remove the NL 1451 } 1452 1453 // Check for ^C here now and then, so recursive :so can be broken. 1454 line_breakcheck(); 1455 break; 1456 } 1457 1458 if (have_read) 1459 return (char_u *)ga.ga_data; 1460 1461 vim_free(ga.ga_data); 1462 return NULL; 1463 } 1464 1465 /* 1466 * Get one full line from a sourced file. 1467 * Called by do_cmdline() when it's called from do_source(). 1468 * 1469 * Return a pointer to the line in allocated memory. 1470 * Return NULL for end-of-file or some error. 1471 */ 1472 char_u * 1473 getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat) 1474 { 1475 struct source_cookie *sp = (struct source_cookie *)cookie; 1476 char_u *line; 1477 char_u *p; 1478 1479 #ifdef FEAT_EVAL 1480 // If breakpoints have been added/deleted need to check for it. 1481 if (sp->dbg_tick < debug_tick) 1482 { 1483 sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum); 1484 sp->dbg_tick = debug_tick; 1485 } 1486 # ifdef FEAT_PROFILE 1487 if (do_profiling == PROF_YES) 1488 script_line_end(); 1489 # endif 1490 #endif 1491 1492 // Set the current sourcing line number. 1493 sourcing_lnum = sp->sourcing_lnum + 1; 1494 1495 // Get current line. If there is a read-ahead line, use it, otherwise get 1496 // one now. 1497 if (sp->finished) 1498 line = NULL; 1499 else if (sp->nextline == NULL) 1500 line = get_one_sourceline(sp); 1501 else 1502 { 1503 line = sp->nextline; 1504 sp->nextline = NULL; 1505 ++sp->sourcing_lnum; 1506 } 1507 #ifdef FEAT_PROFILE 1508 if (line != NULL && do_profiling == PROF_YES) 1509 script_line_start(); 1510 #endif 1511 1512 // Only concatenate lines starting with a \ when 'cpoptions' doesn't 1513 // contain the 'C' flag. 1514 if (line != NULL && do_concat && vim_strchr(p_cpo, CPO_CONCAT) == NULL) 1515 { 1516 // compensate for the one line read-ahead 1517 --sp->sourcing_lnum; 1518 1519 // Get the next line and concatenate it when it starts with a 1520 // backslash. We always need to read the next line, keep it in 1521 // sp->nextline. 1522 /* Also check for a comment in between continuation lines: "\ */ 1523 sp->nextline = get_one_sourceline(sp); 1524 if (sp->nextline != NULL 1525 && (*(p = skipwhite(sp->nextline)) == '\\' 1526 || (p[0] == '"' && p[1] == '\\' && p[2] == ' '))) 1527 { 1528 garray_T ga; 1529 1530 ga_init2(&ga, (int)sizeof(char_u), 400); 1531 ga_concat(&ga, line); 1532 if (*p == '\\') 1533 ga_concat(&ga, p + 1); 1534 for (;;) 1535 { 1536 vim_free(sp->nextline); 1537 sp->nextline = get_one_sourceline(sp); 1538 if (sp->nextline == NULL) 1539 break; 1540 p = skipwhite(sp->nextline); 1541 if (*p == '\\') 1542 { 1543 // Adjust the growsize to the current length to speed up 1544 // concatenating many lines. 1545 if (ga.ga_len > 400) 1546 { 1547 if (ga.ga_len > 8000) 1548 ga.ga_growsize = 8000; 1549 else 1550 ga.ga_growsize = ga.ga_len; 1551 } 1552 ga_concat(&ga, p + 1); 1553 } 1554 else if (p[0] != '"' || p[1] != '\\' || p[2] != ' ') 1555 break; 1556 } 1557 ga_append(&ga, NUL); 1558 vim_free(line); 1559 line = ga.ga_data; 1560 } 1561 } 1562 1563 if (line != NULL && sp->conv.vc_type != CONV_NONE) 1564 { 1565 char_u *s; 1566 1567 // Convert the encoding of the script line. 1568 s = string_convert(&sp->conv, line, NULL); 1569 if (s != NULL) 1570 { 1571 vim_free(line); 1572 line = s; 1573 } 1574 } 1575 1576 #ifdef FEAT_EVAL 1577 // Did we encounter a breakpoint? 1578 if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum) 1579 { 1580 dbg_breakpoint(sp->fname, sourcing_lnum); 1581 // Find next breakpoint. 1582 sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum); 1583 sp->dbg_tick = debug_tick; 1584 } 1585 #endif 1586 1587 return line; 1588 } 1589 1590 /* 1591 * ":scriptencoding": Set encoding conversion for a sourced script. 1592 */ 1593 void 1594 ex_scriptencoding(exarg_T *eap) 1595 { 1596 struct source_cookie *sp; 1597 char_u *name; 1598 1599 if (!getline_equal(eap->getline, eap->cookie, getsourceline)) 1600 { 1601 emsg(_("E167: :scriptencoding used outside of a sourced file")); 1602 return; 1603 } 1604 1605 if (*eap->arg != NUL) 1606 { 1607 name = enc_canonize(eap->arg); 1608 if (name == NULL) // out of memory 1609 return; 1610 } 1611 else 1612 name = eap->arg; 1613 1614 // Setup for conversion from the specified encoding to 'encoding'. 1615 sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie); 1616 convert_setup(&sp->conv, name, p_enc); 1617 1618 if (name != eap->arg) 1619 vim_free(name); 1620 } 1621 1622 /* 1623 * ":scriptversion": Set Vim script version for a sourced script. 1624 */ 1625 void 1626 ex_scriptversion(exarg_T *eap UNUSED) 1627 { 1628 #ifdef FEAT_EVAL 1629 int nr; 1630 1631 if (!getline_equal(eap->getline, eap->cookie, getsourceline)) 1632 { 1633 emsg(_("E984: :scriptversion used outside of a sourced file")); 1634 return; 1635 } 1636 1637 nr = getdigits(&eap->arg); 1638 if (nr == 0 || *eap->arg != NUL) 1639 emsg(_(e_invarg)); 1640 else if (nr > 3) 1641 semsg(_("E999: scriptversion not supported: %d"), nr); 1642 else 1643 current_sctx.sc_version = nr; 1644 #endif 1645 } 1646 1647 #if defined(FEAT_EVAL) || defined(PROTO) 1648 /* 1649 * ":finish": Mark a sourced file as finished. 1650 */ 1651 void 1652 ex_finish(exarg_T *eap) 1653 { 1654 if (getline_equal(eap->getline, eap->cookie, getsourceline)) 1655 do_finish(eap, FALSE); 1656 else 1657 emsg(_("E168: :finish used outside of a sourced file")); 1658 } 1659 1660 /* 1661 * Mark a sourced file as finished. Possibly makes the ":finish" pending. 1662 * Also called for a pending finish at the ":endtry" or after returning from 1663 * an extra do_cmdline(). "reanimate" is used in the latter case. 1664 */ 1665 void 1666 do_finish(exarg_T *eap, int reanimate) 1667 { 1668 int idx; 1669 1670 if (reanimate) 1671 ((struct source_cookie *)getline_cookie(eap->getline, 1672 eap->cookie))->finished = FALSE; 1673 1674 // Cleanup (and inactivate) conditionals, but stop when a try conditional 1675 // not in its finally clause (which then is to be executed next) is found. 1676 // In this case, make the ":finish" pending for execution at the ":endtry". 1677 // Otherwise, finish normally. 1678 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 1679 if (idx >= 0) 1680 { 1681 eap->cstack->cs_pending[idx] = CSTP_FINISH; 1682 report_make_pending(CSTP_FINISH, NULL); 1683 } 1684 else 1685 ((struct source_cookie *)getline_cookie(eap->getline, 1686 eap->cookie))->finished = TRUE; 1687 } 1688 1689 1690 /* 1691 * Return TRUE when a sourced file had the ":finish" command: Don't give error 1692 * message for missing ":endif". 1693 * Return FALSE when not sourcing a file. 1694 */ 1695 int 1696 source_finished( 1697 char_u *(*fgetline)(int, void *, int, int), 1698 void *cookie) 1699 { 1700 return (getline_equal(fgetline, cookie, getsourceline) 1701 && ((struct source_cookie *)getline_cookie( 1702 fgetline, cookie))->finished); 1703 } 1704 1705 /* 1706 * Return the autoload script name for a function or variable name. 1707 * Returns NULL when out of memory. 1708 * Caller must make sure that "name" contains AUTOLOAD_CHAR. 1709 */ 1710 char_u * 1711 autoload_name(char_u *name) 1712 { 1713 char_u *p, *q = NULL; 1714 char_u *scriptname; 1715 1716 // Get the script file name: replace '#' with '/', append ".vim". 1717 scriptname = alloc(STRLEN(name) + 14); 1718 if (scriptname == NULL) 1719 return NULL; 1720 STRCPY(scriptname, "autoload/"); 1721 STRCAT(scriptname, name); 1722 for (p = scriptname + 9; (p = vim_strchr(p, AUTOLOAD_CHAR)) != NULL; 1723 q = p, ++p) 1724 *p = '/'; 1725 STRCPY(q, ".vim"); 1726 return scriptname; 1727 } 1728 1729 /* 1730 * If "name" has a package name try autoloading the script for it. 1731 * Return TRUE if a package was loaded. 1732 */ 1733 int 1734 script_autoload( 1735 char_u *name, 1736 int reload) // load script again when already loaded 1737 { 1738 char_u *p; 1739 char_u *scriptname, *tofree; 1740 int ret = FALSE; 1741 int i; 1742 1743 // If there is no '#' after name[0] there is no package name. 1744 p = vim_strchr(name, AUTOLOAD_CHAR); 1745 if (p == NULL || p == name) 1746 return FALSE; 1747 1748 tofree = scriptname = autoload_name(name); 1749 if (scriptname == NULL) 1750 return FALSE; 1751 1752 // Find the name in the list of previously loaded package names. Skip 1753 // "autoload/", it's always the same. 1754 for (i = 0; i < ga_loaded.ga_len; ++i) 1755 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 1756 break; 1757 if (!reload && i < ga_loaded.ga_len) 1758 ret = FALSE; // was loaded already 1759 else 1760 { 1761 // Remember the name if it wasn't loaded already. 1762 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 1763 { 1764 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 1765 tofree = NULL; 1766 } 1767 1768 // Try loading the package from $VIMRUNTIME/autoload/<name>.vim 1769 if (source_runtime(scriptname, 0) == OK) 1770 ret = TRUE; 1771 } 1772 1773 vim_free(tofree); 1774 return ret; 1775 } 1776 #endif 1777