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 * viminfo.c: viminfo related functions 12 */ 13 14 #include "vim.h" 15 #include "version.h" 16 17 #if defined(FEAT_VIMINFO) || defined(PROTO) 18 19 static int viminfo_errcnt; 20 21 /* 22 * Find the parameter represented by the given character (eg ''', ':', '"', or 23 * '/') in the 'viminfo' option and return a pointer to the string after it. 24 * Return NULL if the parameter is not specified in the string. 25 */ 26 static char_u * 27 find_viminfo_parameter(int type) 28 { 29 char_u *p; 30 31 for (p = p_viminfo; *p; ++p) 32 { 33 if (*p == type) 34 return p + 1; 35 if (*p == 'n') // 'n' is always the last one 36 break; 37 p = vim_strchr(p, ','); // skip until next ',' 38 if (p == NULL) // hit the end without finding parameter 39 break; 40 } 41 return NULL; 42 } 43 44 /* 45 * Find the parameter represented by the given character (eg ', :, ", or /), 46 * and return its associated value in the 'viminfo' string. 47 * Only works for number parameters, not for 'r' or 'n'. 48 * If the parameter is not specified in the string or there is no following 49 * number, return -1. 50 */ 51 int 52 get_viminfo_parameter(int type) 53 { 54 char_u *p; 55 56 p = find_viminfo_parameter(type); 57 if (p != NULL && VIM_ISDIGIT(*p)) 58 return atoi((char *)p); 59 return -1; 60 } 61 62 /* 63 * Get the viminfo file name to use. 64 * If "file" is given and not empty, use it (has already been expanded by 65 * cmdline functions). 66 * Otherwise use "-i file_name", value from 'viminfo' or the default, and 67 * expand environment variables. 68 * Returns an allocated string. NULL when out of memory. 69 */ 70 static char_u * 71 viminfo_filename(char_u *file) 72 { 73 if (file == NULL || *file == NUL) 74 { 75 if (*p_viminfofile != NUL) 76 file = p_viminfofile; 77 else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL) 78 { 79 #ifdef VIMINFO_FILE2 80 # ifdef VMS 81 if (mch_getenv((char_u *)"SYS$LOGIN") == NULL) 82 # else 83 # ifdef MSWIN 84 // Use $VIM only if $HOME is the default "C:/". 85 if (STRCMP(vim_getenv((char_u *)"HOME", NULL), "C:/") == 0 86 && mch_getenv((char_u *)"HOME") == NULL) 87 # else 88 if (mch_getenv((char_u *)"HOME") == NULL) 89 # endif 90 # endif 91 { 92 // don't use $VIM when not available. 93 expand_env((char_u *)"$VIM", NameBuff, MAXPATHL); 94 if (STRCMP("$VIM", NameBuff) != 0) // $VIM was expanded 95 file = (char_u *)VIMINFO_FILE2; 96 else 97 file = (char_u *)VIMINFO_FILE; 98 } 99 else 100 #endif 101 file = (char_u *)VIMINFO_FILE; 102 } 103 expand_env(file, NameBuff, MAXPATHL); 104 file = NameBuff; 105 } 106 return vim_strsave(file); 107 } 108 109 /* 110 * write string to viminfo file 111 * - replace CTRL-V with CTRL-V CTRL-V 112 * - replace '\n' with CTRL-V 'n' 113 * - add a '\n' at the end 114 * 115 * For a long line: 116 * - write " CTRL-V <length> \n " in first line 117 * - write " < <string> \n " in second line 118 */ 119 static void 120 viminfo_writestring(FILE *fd, char_u *p) 121 { 122 int c; 123 char_u *s; 124 int len = 0; 125 126 for (s = p; *s != NUL; ++s) 127 { 128 if (*s == Ctrl_V || *s == '\n') 129 ++len; 130 ++len; 131 } 132 133 // If the string will be too long, write its length and put it in the next 134 // line. Take into account that some room is needed for what comes before 135 // the string (e.g., variable name). Add something to the length for the 136 // '<', NL and trailing NUL. 137 if (len > LSIZE / 2) 138 fprintf(fd, IF_EB("\026%d\n<", CTRL_V_STR "%d\n<"), len + 3); 139 140 while ((c = *p++) != NUL) 141 { 142 if (c == Ctrl_V || c == '\n') 143 { 144 putc(Ctrl_V, fd); 145 if (c == '\n') 146 c = 'n'; 147 } 148 putc(c, fd); 149 } 150 putc('\n', fd); 151 } 152 153 /* 154 * Write a string in quotes that barline_parse() can read back. 155 * Breaks the line in less than LSIZE pieces when needed. 156 * Returns remaining characters in the line. 157 */ 158 static int 159 barline_writestring(FILE *fd, char_u *s, int remaining_start) 160 { 161 char_u *p; 162 int remaining = remaining_start; 163 int len = 2; 164 165 // Count the number of characters produced, including quotes. 166 for (p = s; *p != NUL; ++p) 167 { 168 if (*p == NL) 169 len += 2; 170 else if (*p == '"' || *p == '\\') 171 len += 2; 172 else 173 ++len; 174 } 175 if (len > remaining - 2) 176 { 177 fprintf(fd, ">%d\n|<", len); 178 remaining = LSIZE - 20; 179 } 180 181 putc('"', fd); 182 for (p = s; *p != NUL; ++p) 183 { 184 if (*p == NL) 185 { 186 putc('\\', fd); 187 putc('n', fd); 188 --remaining; 189 } 190 else if (*p == '"' || *p == '\\') 191 { 192 putc('\\', fd); 193 putc(*p, fd); 194 --remaining; 195 } 196 else 197 putc(*p, fd); 198 --remaining; 199 200 if (remaining < 3) 201 { 202 putc('\n', fd); 203 putc('|', fd); 204 putc('<', fd); 205 // Leave enough space for another continuation. 206 remaining = LSIZE - 20; 207 } 208 } 209 putc('"', fd); 210 return remaining - 2; 211 } 212 213 /* 214 * Check string read from viminfo file. 215 * Remove '\n' at the end of the line. 216 * - replace CTRL-V CTRL-V with CTRL-V 217 * - replace CTRL-V 'n' with '\n' 218 * 219 * Check for a long line as written by viminfo_writestring(). 220 * 221 * Return the string in allocated memory (NULL when out of memory). 222 */ 223 static char_u * 224 viminfo_readstring( 225 vir_T *virp, 226 int off, // offset for virp->vir_line 227 int convert UNUSED) // convert the string 228 { 229 char_u *retval; 230 char_u *s, *d; 231 long len; 232 233 if (virp->vir_line[off] == Ctrl_V && vim_isdigit(virp->vir_line[off + 1])) 234 { 235 len = atol((char *)virp->vir_line + off + 1); 236 retval = lalloc(len, TRUE); 237 if (retval == NULL) 238 { 239 // Line too long? File messed up? Skip next line. 240 (void)vim_fgets(virp->vir_line, 10, virp->vir_fd); 241 return NULL; 242 } 243 (void)vim_fgets(retval, (int)len, virp->vir_fd); 244 s = retval + 1; // Skip the leading '<' 245 } 246 else 247 { 248 retval = vim_strsave(virp->vir_line + off); 249 if (retval == NULL) 250 return NULL; 251 s = retval; 252 } 253 254 // Change CTRL-V CTRL-V to CTRL-V and CTRL-V n to \n in-place. 255 d = retval; 256 while (*s != NUL && *s != '\n') 257 { 258 if (s[0] == Ctrl_V && s[1] != NUL) 259 { 260 if (s[1] == 'n') 261 *d++ = '\n'; 262 else 263 *d++ = Ctrl_V; 264 s += 2; 265 } 266 else 267 *d++ = *s++; 268 } 269 *d = NUL; 270 271 if (convert && virp->vir_conv.vc_type != CONV_NONE && *retval != NUL) 272 { 273 d = string_convert(&virp->vir_conv, retval, NULL); 274 if (d != NULL) 275 { 276 vim_free(retval); 277 retval = d; 278 } 279 } 280 281 return retval; 282 } 283 284 /* 285 * Read a line from the viminfo file. 286 * Returns TRUE for end-of-file; 287 */ 288 static int 289 viminfo_readline(vir_T *virp) 290 { 291 return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd); 292 } 293 294 static int 295 read_viminfo_bufferlist( 296 vir_T *virp, 297 int writing) 298 { 299 char_u *tab; 300 linenr_T lnum; 301 colnr_T col; 302 buf_T *buf; 303 char_u *sfname; 304 char_u *xline; 305 306 // Handle long line and escaped characters. 307 xline = viminfo_readstring(virp, 1, FALSE); 308 309 // don't read in if there are files on the command-line or if writing: 310 if (xline != NULL && !writing && ARGCOUNT == 0 311 && find_viminfo_parameter('%') != NULL) 312 { 313 // Format is: <fname> Tab <lnum> Tab <col>. 314 // Watch out for a Tab in the file name, work from the end. 315 lnum = 0; 316 col = 0; 317 tab = vim_strrchr(xline, '\t'); 318 if (tab != NULL) 319 { 320 *tab++ = '\0'; 321 col = (colnr_T)atoi((char *)tab); 322 tab = vim_strrchr(xline, '\t'); 323 if (tab != NULL) 324 { 325 *tab++ = '\0'; 326 lnum = atol((char *)tab); 327 } 328 } 329 330 // Expand "~/" in the file name at "line + 1" to a full path. 331 // Then try shortening it by comparing with the current directory 332 expand_env(xline, NameBuff, MAXPATHL); 333 sfname = shorten_fname1(NameBuff); 334 335 buf = buflist_new(NameBuff, sfname, (linenr_T)0, BLN_LISTED); 336 if (buf != NULL) // just in case... 337 { 338 buf->b_last_cursor.lnum = lnum; 339 buf->b_last_cursor.col = col; 340 buflist_setfpos(buf, curwin, lnum, col, FALSE); 341 } 342 } 343 vim_free(xline); 344 345 return viminfo_readline(virp); 346 } 347 348 /* 349 * Return TRUE if "name" is on removable media (depending on 'viminfo'). 350 */ 351 static int 352 removable(char_u *name) 353 { 354 char_u *p; 355 char_u part[51]; 356 int retval = FALSE; 357 size_t n; 358 359 name = home_replace_save(NULL, name); 360 if (name != NULL) 361 { 362 for (p = p_viminfo; *p; ) 363 { 364 copy_option_part(&p, part, 51, ", "); 365 if (part[0] == 'r') 366 { 367 n = STRLEN(part + 1); 368 if (MB_STRNICMP(part + 1, name, n) == 0) 369 { 370 retval = TRUE; 371 break; 372 } 373 } 374 } 375 vim_free(name); 376 } 377 return retval; 378 } 379 380 static void 381 write_viminfo_bufferlist(FILE *fp) 382 { 383 buf_T *buf; 384 win_T *win; 385 tabpage_T *tp; 386 char_u *line; 387 int max_buffers; 388 389 if (find_viminfo_parameter('%') == NULL) 390 return; 391 392 // Without a number -1 is returned: do all buffers. 393 max_buffers = get_viminfo_parameter('%'); 394 395 // Allocate room for the file name, lnum and col. 396 #define LINE_BUF_LEN (MAXPATHL + 40) 397 line = alloc(LINE_BUF_LEN); 398 if (line == NULL) 399 return; 400 401 FOR_ALL_TAB_WINDOWS(tp, win) 402 set_last_cursor(win); 403 404 fputs(_("\n# Buffer list:\n"), fp); 405 FOR_ALL_BUFFERS(buf) 406 { 407 if (buf->b_fname == NULL 408 || !buf->b_p_bl 409 #ifdef FEAT_QUICKFIX 410 || bt_quickfix(buf) 411 #endif 412 #ifdef FEAT_TERMINAL 413 || bt_terminal(buf) 414 #endif 415 || removable(buf->b_ffname)) 416 continue; 417 418 if (max_buffers-- == 0) 419 break; 420 putc('%', fp); 421 home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE); 422 vim_snprintf_add((char *)line, LINE_BUF_LEN, "\t%ld\t%d", 423 (long)buf->b_last_cursor.lnum, 424 buf->b_last_cursor.col); 425 viminfo_writestring(fp, line); 426 } 427 vim_free(line); 428 } 429 430 #if defined(FEAT_CMDHIST) || defined(PROTO) 431 /* 432 * Buffers for history read from a viminfo file. Only valid while reading. 433 */ 434 static histentry_T *viminfo_history[HIST_COUNT] = 435 {NULL, NULL, NULL, NULL, NULL}; 436 static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0, 0}; 437 static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0, 0}; 438 static int viminfo_add_at_front = FALSE; 439 440 /* 441 * Translate a history type number to the associated character. 442 */ 443 static int 444 hist_type2char( 445 int type, 446 int use_question) // use '?' instead of '/' 447 { 448 if (type == HIST_CMD) 449 return ':'; 450 if (type == HIST_SEARCH) 451 { 452 if (use_question) 453 return '?'; 454 else 455 return '/'; 456 } 457 if (type == HIST_EXPR) 458 return '='; 459 return '@'; 460 } 461 462 /* 463 * Prepare for reading the history from the viminfo file. 464 * This allocates history arrays to store the read history lines. 465 */ 466 static void 467 prepare_viminfo_history(int asklen, int writing) 468 { 469 int i; 470 int num; 471 int type; 472 int len; 473 int hislen; 474 475 init_history(); 476 hislen = get_hislen(); 477 viminfo_add_at_front = (asklen != 0 && !writing); 478 if (asklen > hislen) 479 asklen = hislen; 480 481 for (type = 0; type < HIST_COUNT; ++type) 482 { 483 histentry_T *histentry = get_histentry(type); 484 485 // Count the number of empty spaces in the history list. Entries read 486 // from viminfo previously are also considered empty. If there are 487 // more spaces available than we request, then fill them up. 488 for (i = 0, num = 0; i < hislen; i++) 489 if (histentry[i].hisstr == NULL || histentry[i].viminfo) 490 num++; 491 len = asklen; 492 if (num > len) 493 len = num; 494 if (len <= 0) 495 viminfo_history[type] = NULL; 496 else 497 viminfo_history[type] = LALLOC_MULT(histentry_T, len); 498 if (viminfo_history[type] == NULL) 499 len = 0; 500 viminfo_hislen[type] = len; 501 viminfo_hisidx[type] = 0; 502 } 503 } 504 505 /* 506 * Accept a line from the viminfo, store it in the history array when it's 507 * new. 508 */ 509 static int 510 read_viminfo_history(vir_T *virp, int writing) 511 { 512 int type; 513 long_u len; 514 char_u *val; 515 char_u *p; 516 517 type = hist_char2type(virp->vir_line[0]); 518 if (viminfo_hisidx[type] < viminfo_hislen[type]) 519 { 520 val = viminfo_readstring(virp, 1, TRUE); 521 if (val != NULL && *val != NUL) 522 { 523 int sep = (*val == ' ' ? NUL : *val); 524 525 if (!in_history(type, val + (type == HIST_SEARCH), 526 viminfo_add_at_front, sep, writing)) 527 { 528 // Need to re-allocate to append the separator byte. 529 len = STRLEN(val); 530 p = alloc(len + 2); 531 if (p != NULL) 532 { 533 if (type == HIST_SEARCH) 534 { 535 // Search entry: Move the separator from the first 536 // column to after the NUL. 537 mch_memmove(p, val + 1, (size_t)len); 538 p[len] = sep; 539 } 540 else 541 { 542 // Not a search entry: No separator in the viminfo 543 // file, add a NUL separator. 544 mch_memmove(p, val, (size_t)len + 1); 545 p[len + 1] = NUL; 546 } 547 viminfo_history[type][viminfo_hisidx[type]].hisstr = p; 548 viminfo_history[type][viminfo_hisidx[type]].time_set = 0; 549 viminfo_history[type][viminfo_hisidx[type]].viminfo = TRUE; 550 viminfo_history[type][viminfo_hisidx[type]].hisnum = 0; 551 viminfo_hisidx[type]++; 552 } 553 } 554 } 555 vim_free(val); 556 } 557 return viminfo_readline(virp); 558 } 559 560 /* 561 * Accept a new style history line from the viminfo, store it in the history 562 * array when it's new. 563 */ 564 static void 565 handle_viminfo_history( 566 garray_T *values, 567 int writing) 568 { 569 int type; 570 long_u len; 571 char_u *val; 572 char_u *p; 573 bval_T *vp = (bval_T *)values->ga_data; 574 575 // Check the format: 576 // |{bartype},{histtype},{timestamp},{separator},"text" 577 if (values->ga_len < 4 578 || vp[0].bv_type != BVAL_NR 579 || vp[1].bv_type != BVAL_NR 580 || (vp[2].bv_type != BVAL_NR && vp[2].bv_type != BVAL_EMPTY) 581 || vp[3].bv_type != BVAL_STRING) 582 return; 583 584 type = vp[0].bv_nr; 585 if (type >= HIST_COUNT) 586 return; 587 if (viminfo_hisidx[type] < viminfo_hislen[type]) 588 { 589 val = vp[3].bv_string; 590 if (val != NULL && *val != NUL) 591 { 592 int sep = type == HIST_SEARCH && vp[2].bv_type == BVAL_NR 593 ? vp[2].bv_nr : NUL; 594 int idx; 595 int overwrite = FALSE; 596 597 if (!in_history(type, val, viminfo_add_at_front, sep, writing)) 598 { 599 // If lines were written by an older Vim we need to avoid 600 // getting duplicates. See if the entry already exists. 601 for (idx = 0; idx < viminfo_hisidx[type]; ++idx) 602 { 603 p = viminfo_history[type][idx].hisstr; 604 if (STRCMP(val, p) == 0 605 && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1])) 606 { 607 overwrite = TRUE; 608 break; 609 } 610 } 611 612 if (!overwrite) 613 { 614 // Need to re-allocate to append the separator byte. 615 len = vp[3].bv_len; 616 p = alloc(len + 2); 617 } 618 else 619 len = 0; // for picky compilers 620 if (p != NULL) 621 { 622 viminfo_history[type][idx].time_set = vp[1].bv_nr; 623 if (!overwrite) 624 { 625 mch_memmove(p, val, (size_t)len + 1); 626 // Put the separator after the NUL. 627 p[len + 1] = sep; 628 viminfo_history[type][idx].hisstr = p; 629 viminfo_history[type][idx].hisnum = 0; 630 viminfo_history[type][idx].viminfo = TRUE; 631 viminfo_hisidx[type]++; 632 } 633 } 634 } 635 } 636 } 637 } 638 639 /* 640 * Concatenate history lines from viminfo after the lines typed in this Vim. 641 */ 642 static void 643 concat_history(int type) 644 { 645 int idx; 646 int i; 647 int hislen = get_hislen(); 648 histentry_T *histentry = get_histentry(type); 649 int *hisidx = get_hisidx(type); 650 int *hisnum = get_hisnum(type); 651 652 idx = *hisidx + viminfo_hisidx[type]; 653 if (idx >= hislen) 654 idx -= hislen; 655 else if (idx < 0) 656 idx = hislen - 1; 657 if (viminfo_add_at_front) 658 *hisidx = idx; 659 else 660 { 661 if (*hisidx == -1) 662 *hisidx = hislen - 1; 663 do 664 { 665 if (histentry[idx].hisstr != NULL || histentry[idx].viminfo) 666 break; 667 if (++idx == hislen) 668 idx = 0; 669 } while (idx != *hisidx); 670 if (idx != *hisidx && --idx < 0) 671 idx = hislen - 1; 672 } 673 for (i = 0; i < viminfo_hisidx[type]; i++) 674 { 675 vim_free(histentry[idx].hisstr); 676 histentry[idx].hisstr = viminfo_history[type][i].hisstr; 677 histentry[idx].viminfo = TRUE; 678 histentry[idx].time_set = viminfo_history[type][i].time_set; 679 if (--idx < 0) 680 idx = hislen - 1; 681 } 682 idx += 1; 683 idx %= hislen; 684 for (i = 0; i < viminfo_hisidx[type]; i++) 685 { 686 histentry[idx++].hisnum = ++*hisnum; 687 idx %= hislen; 688 } 689 } 690 691 static int 692 sort_hist(const void *s1, const void *s2) 693 { 694 histentry_T *p1 = *(histentry_T **)s1; 695 histentry_T *p2 = *(histentry_T **)s2; 696 697 if (p1->time_set < p2->time_set) return -1; 698 if (p1->time_set > p2->time_set) return 1; 699 return 0; 700 } 701 702 /* 703 * Merge history lines from viminfo and lines typed in this Vim based on the 704 * timestamp; 705 */ 706 static void 707 merge_history(int type) 708 { 709 int max_len; 710 histentry_T **tot_hist; 711 histentry_T *new_hist; 712 int i; 713 int len; 714 int hislen = get_hislen(); 715 histentry_T *histentry = get_histentry(type); 716 int *hisidx = get_hisidx(type); 717 int *hisnum = get_hisnum(type); 718 719 // Make one long list with all entries. 720 max_len = hislen + viminfo_hisidx[type]; 721 tot_hist = ALLOC_MULT(histentry_T *, max_len); 722 new_hist = ALLOC_MULT(histentry_T, hislen); 723 if (tot_hist == NULL || new_hist == NULL) 724 { 725 vim_free(tot_hist); 726 vim_free(new_hist); 727 return; 728 } 729 for (i = 0; i < viminfo_hisidx[type]; i++) 730 tot_hist[i] = &viminfo_history[type][i]; 731 len = i; 732 for (i = 0; i < hislen; i++) 733 if (histentry[i].hisstr != NULL) 734 tot_hist[len++] = &histentry[i]; 735 736 // Sort the list on timestamp. 737 qsort((void *)tot_hist, (size_t)len, sizeof(histentry_T *), sort_hist); 738 739 // Keep the newest ones. 740 for (i = 0; i < hislen; i++) 741 { 742 if (i < len) 743 { 744 new_hist[i] = *tot_hist[i]; 745 tot_hist[i]->hisstr = NULL; 746 if (new_hist[i].hisnum == 0) 747 new_hist[i].hisnum = ++*hisnum; 748 } 749 else 750 clear_hist_entry(&new_hist[i]); 751 } 752 *hisidx = (i < len ? i : len) - 1; 753 754 // Free what is not kept. 755 for (i = 0; i < viminfo_hisidx[type]; i++) 756 vim_free(viminfo_history[type][i].hisstr); 757 for (i = 0; i < hislen; i++) 758 vim_free(histentry[i].hisstr); 759 vim_free(histentry); 760 set_histentry(type, new_hist); 761 vim_free(tot_hist); 762 } 763 764 /* 765 * Finish reading history lines from viminfo. Not used when writing viminfo. 766 */ 767 static void 768 finish_viminfo_history(vir_T *virp) 769 { 770 int type; 771 int merge = virp->vir_version >= VIMINFO_VERSION_WITH_HISTORY; 772 773 for (type = 0; type < HIST_COUNT; ++type) 774 { 775 if (get_histentry(type) == NULL) 776 continue; 777 778 if (merge) 779 merge_history(type); 780 else 781 concat_history(type); 782 783 VIM_CLEAR(viminfo_history[type]); 784 viminfo_hisidx[type] = 0; 785 } 786 } 787 788 /* 789 * Write history to viminfo file in "fp". 790 * When "merge" is TRUE merge history lines with a previously read viminfo 791 * file, data is in viminfo_history[]. 792 * When "merge" is FALSE just write all history lines. Used for ":wviminfo!". 793 */ 794 static void 795 write_viminfo_history(FILE *fp, int merge) 796 { 797 int i; 798 int type; 799 int num_saved; 800 int round; 801 int hislen; 802 803 init_history(); 804 hislen = get_hislen(); 805 if (hislen == 0) 806 return; 807 for (type = 0; type < HIST_COUNT; ++type) 808 { 809 histentry_T *histentry = get_histentry(type); 810 int *hisidx = get_hisidx(type); 811 812 num_saved = get_viminfo_parameter(hist_type2char(type, FALSE)); 813 if (num_saved == 0) 814 continue; 815 if (num_saved < 0) // Use default 816 num_saved = hislen; 817 fprintf(fp, _("\n# %s History (newest to oldest):\n"), 818 type == HIST_CMD ? _("Command Line") : 819 type == HIST_SEARCH ? _("Search String") : 820 type == HIST_EXPR ? _("Expression") : 821 type == HIST_INPUT ? _("Input Line") : 822 _("Debug Line")); 823 if (num_saved > hislen) 824 num_saved = hislen; 825 826 /* 827 * Merge typed and viminfo history: 828 * round 1: history of typed commands. 829 * round 2: history from recently read viminfo. 830 */ 831 for (round = 1; round <= 2; ++round) 832 { 833 if (round == 1) 834 // start at newest entry, somewhere in the list 835 i = *hisidx; 836 else if (viminfo_hisidx[type] > 0) 837 // start at newest entry, first in the list 838 i = 0; 839 else 840 // empty list 841 i = -1; 842 if (i >= 0) 843 while (num_saved > 0 844 && !(round == 2 && i >= viminfo_hisidx[type])) 845 { 846 char_u *p; 847 time_t timestamp; 848 int c = NUL; 849 850 if (round == 1) 851 { 852 p = histentry[i].hisstr; 853 timestamp = histentry[i].time_set; 854 } 855 else 856 { 857 p = viminfo_history[type] == NULL ? NULL 858 : viminfo_history[type][i].hisstr; 859 timestamp = viminfo_history[type] == NULL ? 0 860 : viminfo_history[type][i].time_set; 861 } 862 863 if (p != NULL && (round == 2 864 || !merge 865 || !histentry[i].viminfo)) 866 { 867 --num_saved; 868 fputc(hist_type2char(type, TRUE), fp); 869 // For the search history: put the separator in the 870 // second column; use a space if there isn't one. 871 if (type == HIST_SEARCH) 872 { 873 c = p[STRLEN(p) + 1]; 874 putc(c == NUL ? ' ' : c, fp); 875 } 876 viminfo_writestring(fp, p); 877 878 { 879 char cbuf[NUMBUFLEN]; 880 881 // New style history with a bar line. Format: 882 // |{bartype},{histtype},{timestamp},{separator},"text" 883 if (c == NUL) 884 cbuf[0] = NUL; 885 else 886 sprintf(cbuf, "%d", c); 887 fprintf(fp, "|%d,%d,%ld,%s,", BARTYPE_HISTORY, 888 type, (long)timestamp, cbuf); 889 barline_writestring(fp, p, LSIZE - 20); 890 putc('\n', fp); 891 } 892 } 893 if (round == 1) 894 { 895 // Decrement index, loop around and stop when back at 896 // the start. 897 if (--i < 0) 898 i = hislen - 1; 899 if (i == *hisidx) 900 break; 901 } 902 else 903 { 904 // Increment index. Stop at the end in the while. 905 ++i; 906 } 907 } 908 } 909 for (i = 0; i < viminfo_hisidx[type]; ++i) 910 if (viminfo_history[type] != NULL) 911 vim_free(viminfo_history[type][i].hisstr); 912 VIM_CLEAR(viminfo_history[type]); 913 viminfo_hisidx[type] = 0; 914 } 915 } 916 #endif // FEAT_CMDHIST 917 918 static void 919 write_viminfo_barlines(vir_T *virp, FILE *fp_out) 920 { 921 int i; 922 garray_T *gap = &virp->vir_barlines; 923 int seen_useful = FALSE; 924 char *line; 925 926 if (gap->ga_len > 0) 927 { 928 fputs(_("\n# Bar lines, copied verbatim:\n"), fp_out); 929 930 // Skip over continuation lines until seeing a useful line. 931 for (i = 0; i < gap->ga_len; ++i) 932 { 933 line = ((char **)(gap->ga_data))[i]; 934 if (seen_useful || line[1] != '<') 935 { 936 fputs(line, fp_out); 937 seen_useful = TRUE; 938 } 939 } 940 } 941 } 942 943 /* 944 * Parse a viminfo line starting with '|'. 945 * Add each decoded value to "values". 946 * Returns TRUE if the next line is to be read after using the parsed values. 947 */ 948 static int 949 barline_parse(vir_T *virp, char_u *text, garray_T *values) 950 { 951 char_u *p = text; 952 char_u *nextp = NULL; 953 char_u *buf = NULL; 954 bval_T *value; 955 int i; 956 int allocated = FALSE; 957 int eof; 958 char_u *sconv; 959 int converted; 960 961 while (*p == ',') 962 { 963 ++p; 964 if (ga_grow(values, 1) == FAIL) 965 break; 966 value = (bval_T *)(values->ga_data) + values->ga_len; 967 968 if (*p == '>') 969 { 970 // Need to read a continuation line. Put strings in allocated 971 // memory, because virp->vir_line is overwritten. 972 if (!allocated) 973 { 974 for (i = 0; i < values->ga_len; ++i) 975 { 976 bval_T *vp = (bval_T *)(values->ga_data) + i; 977 978 if (vp->bv_type == BVAL_STRING && !vp->bv_allocated) 979 { 980 vp->bv_string = vim_strnsave(vp->bv_string, vp->bv_len); 981 vp->bv_allocated = TRUE; 982 } 983 } 984 allocated = TRUE; 985 } 986 987 if (vim_isdigit(p[1])) 988 { 989 size_t len; 990 size_t todo; 991 size_t n; 992 993 // String value was split into lines that are each shorter 994 // than LSIZE: 995 // |{bartype},>{length of "{text}{text2}"} 996 // |<"{text1} 997 // |<{text2}",{value} 998 // Length includes the quotes. 999 ++p; 1000 len = getdigits(&p); 1001 buf = alloc((int)(len + 1)); 1002 if (buf == NULL) 1003 return TRUE; 1004 p = buf; 1005 for (todo = len; todo > 0; todo -= n) 1006 { 1007 eof = viminfo_readline(virp); 1008 if (eof || virp->vir_line[0] != '|' 1009 || virp->vir_line[1] != '<') 1010 { 1011 // File was truncated or garbled. Read another line if 1012 // this one starts with '|'. 1013 vim_free(buf); 1014 return eof || virp->vir_line[0] == '|'; 1015 } 1016 // Get length of text, excluding |< and NL chars. 1017 n = STRLEN(virp->vir_line); 1018 while (n > 0 && (virp->vir_line[n - 1] == NL 1019 || virp->vir_line[n - 1] == CAR)) 1020 --n; 1021 n -= 2; 1022 if (n > todo) 1023 { 1024 // more values follow after the string 1025 nextp = virp->vir_line + 2 + todo; 1026 n = todo; 1027 } 1028 mch_memmove(p, virp->vir_line + 2, n); 1029 p += n; 1030 } 1031 *p = NUL; 1032 p = buf; 1033 } 1034 else 1035 { 1036 // Line ending in ">" continues in the next line: 1037 // |{bartype},{lots of values},> 1038 // |<{value},{value} 1039 eof = viminfo_readline(virp); 1040 if (eof || virp->vir_line[0] != '|' 1041 || virp->vir_line[1] != '<') 1042 // File was truncated or garbled. Read another line if 1043 // this one starts with '|'. 1044 return eof || virp->vir_line[0] == '|'; 1045 p = virp->vir_line + 2; 1046 } 1047 } 1048 1049 if (isdigit(*p)) 1050 { 1051 value->bv_type = BVAL_NR; 1052 value->bv_nr = getdigits(&p); 1053 ++values->ga_len; 1054 } 1055 else if (*p == '"') 1056 { 1057 int len = 0; 1058 char_u *s = p; 1059 1060 // Unescape special characters in-place. 1061 ++p; 1062 while (*p != '"') 1063 { 1064 if (*p == NL || *p == NUL) 1065 return TRUE; // syntax error, drop the value 1066 if (*p == '\\') 1067 { 1068 ++p; 1069 if (*p == 'n') 1070 s[len++] = '\n'; 1071 else 1072 s[len++] = *p; 1073 ++p; 1074 } 1075 else 1076 s[len++] = *p++; 1077 } 1078 ++p; 1079 s[len] = NUL; 1080 1081 converted = FALSE; 1082 if (virp->vir_conv.vc_type != CONV_NONE && *s != NUL) 1083 { 1084 sconv = string_convert(&virp->vir_conv, s, NULL); 1085 if (sconv != NULL) 1086 { 1087 if (s == buf) 1088 vim_free(s); 1089 s = sconv; 1090 buf = s; 1091 converted = TRUE; 1092 } 1093 } 1094 1095 // Need to copy in allocated memory if the string wasn't allocated 1096 // above and we did allocate before, thus vir_line may change. 1097 if (s != buf && allocated) 1098 s = vim_strsave(s); 1099 value->bv_string = s; 1100 value->bv_type = BVAL_STRING; 1101 value->bv_len = len; 1102 value->bv_allocated = allocated || converted; 1103 ++values->ga_len; 1104 if (nextp != NULL) 1105 { 1106 // values following a long string 1107 p = nextp; 1108 nextp = NULL; 1109 } 1110 } 1111 else if (*p == ',') 1112 { 1113 value->bv_type = BVAL_EMPTY; 1114 ++values->ga_len; 1115 } 1116 else 1117 break; 1118 } 1119 return TRUE; 1120 } 1121 1122 static void 1123 write_viminfo_version(FILE *fp_out) 1124 { 1125 fprintf(fp_out, "# Viminfo version\n|%d,%d\n\n", 1126 BARTYPE_VERSION, VIMINFO_VERSION); 1127 } 1128 1129 static int 1130 no_viminfo(void) 1131 { 1132 // "vim -i NONE" does not read or write a viminfo file 1133 return STRCMP(p_viminfofile, "NONE") == 0; 1134 } 1135 1136 /* 1137 * Report an error for reading a viminfo file. 1138 * Count the number of errors. When there are more than 10, return TRUE. 1139 */ 1140 static int 1141 viminfo_error(char *errnum, char *message, char_u *line) 1142 { 1143 vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "), 1144 errnum, message); 1145 STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff) - 1); 1146 if (IObuff[STRLEN(IObuff) - 1] == '\n') 1147 IObuff[STRLEN(IObuff) - 1] = NUL; 1148 emsg((char *)IObuff); 1149 if (++viminfo_errcnt >= 10) 1150 { 1151 emsg(_("E136: viminfo: Too many errors, skipping rest of file")); 1152 return TRUE; 1153 } 1154 return FALSE; 1155 } 1156 1157 /* 1158 * Compare the 'encoding' value in the viminfo file with the current value of 1159 * 'encoding'. If different and the 'c' flag is in 'viminfo', setup for 1160 * conversion of text with iconv() in viminfo_readstring(). 1161 */ 1162 static int 1163 viminfo_encoding(vir_T *virp) 1164 { 1165 char_u *p; 1166 int i; 1167 1168 if (get_viminfo_parameter('c') != 0) 1169 { 1170 p = vim_strchr(virp->vir_line, '='); 1171 if (p != NULL) 1172 { 1173 // remove trailing newline 1174 ++p; 1175 for (i = 0; vim_isprintc(p[i]); ++i) 1176 ; 1177 p[i] = NUL; 1178 1179 convert_setup(&virp->vir_conv, p, p_enc); 1180 } 1181 } 1182 return viminfo_readline(virp); 1183 } 1184 1185 #if defined(FEAT_EVAL) || defined(PROTO) 1186 /* 1187 * Restore global vars that start with a capital from the viminfo file 1188 */ 1189 static int 1190 read_viminfo_varlist(vir_T *virp, int writing) 1191 { 1192 char_u *tab; 1193 int type = VAR_NUMBER; 1194 typval_T tv; 1195 funccal_entry_T funccal_entry; 1196 1197 if (!writing && (find_viminfo_parameter('!') != NULL)) 1198 { 1199 tab = vim_strchr(virp->vir_line + 1, '\t'); 1200 if (tab != NULL) 1201 { 1202 *tab++ = '\0'; // isolate the variable name 1203 switch (*tab) 1204 { 1205 case 'S': type = VAR_STRING; break; 1206 #ifdef FEAT_FLOAT 1207 case 'F': type = VAR_FLOAT; break; 1208 #endif 1209 case 'D': type = VAR_DICT; break; 1210 case 'L': type = VAR_LIST; break; 1211 case 'B': type = VAR_BLOB; break; 1212 case 'X': type = VAR_SPECIAL; break; 1213 } 1214 1215 tab = vim_strchr(tab, '\t'); 1216 if (tab != NULL) 1217 { 1218 tv.v_type = type; 1219 if (type == VAR_STRING || type == VAR_DICT 1220 || type == VAR_LIST || type == VAR_BLOB) 1221 tv.vval.v_string = viminfo_readstring(virp, 1222 (int)(tab - virp->vir_line + 1), TRUE); 1223 #ifdef FEAT_FLOAT 1224 else if (type == VAR_FLOAT) 1225 (void)string2float(tab + 1, &tv.vval.v_float); 1226 #endif 1227 else 1228 tv.vval.v_number = atol((char *)tab + 1); 1229 if (type == VAR_DICT || type == VAR_LIST) 1230 { 1231 typval_T *etv = eval_expr(tv.vval.v_string, NULL); 1232 1233 if (etv == NULL) 1234 // Failed to parse back the dict or list, use it as a 1235 // string. 1236 tv.v_type = VAR_STRING; 1237 else 1238 { 1239 vim_free(tv.vval.v_string); 1240 tv = *etv; 1241 vim_free(etv); 1242 } 1243 } 1244 else if (type == VAR_BLOB) 1245 { 1246 blob_T *blob = string2blob(tv.vval.v_string); 1247 1248 if (blob == NULL) 1249 // Failed to parse back the blob, use it as a string. 1250 tv.v_type = VAR_STRING; 1251 else 1252 { 1253 vim_free(tv.vval.v_string); 1254 tv.v_type = VAR_BLOB; 1255 tv.vval.v_blob = blob; 1256 } 1257 } 1258 1259 // when in a function use global variables 1260 save_funccal(&funccal_entry); 1261 set_var(virp->vir_line + 1, &tv, FALSE); 1262 restore_funccal(); 1263 1264 if (tv.v_type == VAR_STRING) 1265 vim_free(tv.vval.v_string); 1266 else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST || 1267 tv.v_type == VAR_BLOB) 1268 clear_tv(&tv); 1269 } 1270 } 1271 } 1272 1273 return viminfo_readline(virp); 1274 } 1275 1276 /* 1277 * Write global vars that start with a capital to the viminfo file 1278 */ 1279 static void 1280 write_viminfo_varlist(FILE *fp) 1281 { 1282 hashitem_T *hi; 1283 dictitem_T *this_var; 1284 int todo; 1285 char *s = ""; 1286 char_u *p; 1287 char_u *tofree; 1288 char_u numbuf[NUMBUFLEN]; 1289 1290 if (find_viminfo_parameter('!') == NULL) 1291 return; 1292 1293 fputs(_("\n# global variables:\n"), fp); 1294 1295 todo = (int)globvarht.ht_used; 1296 for (hi = globvarht.ht_array; todo > 0; ++hi) 1297 { 1298 if (!HASHITEM_EMPTY(hi)) 1299 { 1300 --todo; 1301 this_var = HI2DI(hi); 1302 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 1303 { 1304 switch (this_var->di_tv.v_type) 1305 { 1306 case VAR_STRING: s = "STR"; break; 1307 case VAR_NUMBER: s = "NUM"; break; 1308 case VAR_FLOAT: s = "FLO"; break; 1309 case VAR_DICT: s = "DIC"; break; 1310 case VAR_LIST: s = "LIS"; break; 1311 case VAR_BLOB: s = "BLO"; break; 1312 case VAR_SPECIAL: s = "XPL"; break; 1313 1314 case VAR_UNKNOWN: 1315 case VAR_FUNC: 1316 case VAR_PARTIAL: 1317 case VAR_JOB: 1318 case VAR_CHANNEL: 1319 continue; 1320 } 1321 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 1322 if (this_var->di_tv.v_type == VAR_SPECIAL) 1323 { 1324 sprintf((char *)numbuf, "%ld", 1325 (long)this_var->di_tv.vval.v_number); 1326 p = numbuf; 1327 tofree = NULL; 1328 } 1329 else 1330 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 1331 if (p != NULL) 1332 viminfo_writestring(fp, p); 1333 vim_free(tofree); 1334 } 1335 } 1336 } 1337 } 1338 #endif // FEAT_EVAL 1339 1340 static int 1341 read_viminfo_sub_string(vir_T *virp, int force) 1342 { 1343 if (force || get_old_sub() == NULL) 1344 set_old_sub(viminfo_readstring(virp, 1, TRUE)); 1345 return viminfo_readline(virp); 1346 } 1347 1348 static void 1349 write_viminfo_sub_string(FILE *fp) 1350 { 1351 char_u *old_sub = get_old_sub(); 1352 1353 if (get_viminfo_parameter('/') != 0 && old_sub != NULL) 1354 { 1355 fputs(_("\n# Last Substitute String:\n$"), fp); 1356 viminfo_writestring(fp, old_sub); 1357 } 1358 } 1359 1360 /* 1361 * Functions relating to reading/writing the search pattern from viminfo 1362 */ 1363 1364 static int 1365 read_viminfo_search_pattern(vir_T *virp, int force) 1366 { 1367 char_u *lp; 1368 int idx = -1; 1369 int magic = FALSE; 1370 int no_scs = FALSE; 1371 int off_line = FALSE; 1372 int off_end = 0; 1373 long off = 0; 1374 int setlast = FALSE; 1375 #ifdef FEAT_SEARCH_EXTRA 1376 static int hlsearch_on = FALSE; 1377 #endif 1378 char_u *val; 1379 spat_T *spat; 1380 1381 // Old line types: 1382 // "/pat", "&pat": search/subst. pat 1383 // "~/pat", "~&pat": last used search/subst. pat 1384 // New line types: 1385 // "~h", "~H": hlsearch highlighting off/on 1386 // "~<magic><smartcase><line><end><off><last><which>pat" 1387 // <magic>: 'm' off, 'M' on 1388 // <smartcase>: 's' off, 'S' on 1389 // <line>: 'L' line offset, 'l' char offset 1390 // <end>: 'E' from end, 'e' from start 1391 // <off>: decimal, offset 1392 // <last>: '~' last used pattern 1393 // <which>: '/' search pat, '&' subst. pat 1394 lp = virp->vir_line; 1395 if (lp[0] == '~' && (lp[1] == 'm' || lp[1] == 'M')) // new line type 1396 { 1397 if (lp[1] == 'M') // magic on 1398 magic = TRUE; 1399 if (lp[2] == 's') 1400 no_scs = TRUE; 1401 if (lp[3] == 'L') 1402 off_line = TRUE; 1403 if (lp[4] == 'E') 1404 off_end = SEARCH_END; 1405 lp += 5; 1406 off = getdigits(&lp); 1407 } 1408 if (lp[0] == '~') // use this pattern for last-used pattern 1409 { 1410 setlast = TRUE; 1411 lp++; 1412 } 1413 if (lp[0] == '/') 1414 idx = RE_SEARCH; 1415 else if (lp[0] == '&') 1416 idx = RE_SUBST; 1417 #ifdef FEAT_SEARCH_EXTRA 1418 else if (lp[0] == 'h') // ~h: 'hlsearch' highlighting off 1419 hlsearch_on = FALSE; 1420 else if (lp[0] == 'H') // ~H: 'hlsearch' highlighting on 1421 hlsearch_on = TRUE; 1422 #endif 1423 if (idx >= 0) 1424 { 1425 spat = get_spat(idx); 1426 if (force || spat->pat == NULL) 1427 { 1428 val = viminfo_readstring(virp, (int)(lp - virp->vir_line + 1), 1429 TRUE); 1430 if (val != NULL) 1431 { 1432 set_last_search_pat(val, idx, magic, setlast); 1433 vim_free(val); 1434 spat->no_scs = no_scs; 1435 spat->off.line = off_line; 1436 spat->off.end = off_end; 1437 spat->off.off = off; 1438 #ifdef FEAT_SEARCH_EXTRA 1439 if (setlast) 1440 set_no_hlsearch(!hlsearch_on); 1441 #endif 1442 } 1443 } 1444 } 1445 return viminfo_readline(virp); 1446 } 1447 1448 static void 1449 wvsp_one( 1450 FILE *fp, // file to write to 1451 int idx, // spats[] index 1452 char *s, // search pat 1453 int sc) // dir char 1454 { 1455 spat_T *spat = get_spat(idx); 1456 if (spat->pat != NULL) 1457 { 1458 fprintf(fp, _("\n# Last %sSearch Pattern:\n~"), s); 1459 // off.dir is not stored, it's reset to forward 1460 fprintf(fp, "%c%c%c%c%ld%s%c", 1461 spat->magic ? 'M' : 'm', // magic 1462 spat->no_scs ? 's' : 'S', // smartcase 1463 spat->off.line ? 'L' : 'l', // line offset 1464 spat->off.end ? 'E' : 'e', // offset from end 1465 spat->off.off, // offset 1466 get_spat_last_idx() == idx ? "~" : "", // last used pat 1467 sc); 1468 viminfo_writestring(fp, spat->pat); 1469 } 1470 } 1471 1472 static void 1473 write_viminfo_search_pattern(FILE *fp) 1474 { 1475 if (get_viminfo_parameter('/') != 0) 1476 { 1477 #ifdef FEAT_SEARCH_EXTRA 1478 fprintf(fp, "\n# hlsearch on (H) or off (h):\n~%c", 1479 (no_hlsearch || find_viminfo_parameter('h') != NULL) ? 'h' : 'H'); 1480 #endif 1481 wvsp_one(fp, RE_SEARCH, "", '/'); 1482 wvsp_one(fp, RE_SUBST, _("Substitute "), '&'); 1483 } 1484 } 1485 1486 /* 1487 * Functions relating to reading/writing registers from viminfo 1488 */ 1489 1490 static yankreg_T *y_read_regs = NULL; 1491 1492 #define REG_PREVIOUS 1 1493 #define REG_EXEC 2 1494 1495 /* 1496 * Prepare for reading viminfo registers when writing viminfo later. 1497 */ 1498 static void 1499 prepare_viminfo_registers(void) 1500 { 1501 y_read_regs = ALLOC_CLEAR_MULT(yankreg_T, NUM_REGISTERS); 1502 } 1503 1504 static void 1505 finish_viminfo_registers(void) 1506 { 1507 int i; 1508 int j; 1509 1510 if (y_read_regs != NULL) 1511 { 1512 for (i = 0; i < NUM_REGISTERS; ++i) 1513 if (y_read_regs[i].y_array != NULL) 1514 { 1515 for (j = 0; j < y_read_regs[i].y_size; j++) 1516 vim_free(y_read_regs[i].y_array[j]); 1517 vim_free(y_read_regs[i].y_array); 1518 } 1519 VIM_CLEAR(y_read_regs); 1520 } 1521 } 1522 1523 static int 1524 read_viminfo_register(vir_T *virp, int force) 1525 { 1526 int eof; 1527 int do_it = TRUE; 1528 int size; 1529 int limit; 1530 int i; 1531 int set_prev = FALSE; 1532 char_u *str; 1533 char_u **array = NULL; 1534 int new_type = MCHAR; // init to shut up compiler 1535 colnr_T new_width = 0; // init to shut up compiler 1536 yankreg_T *y_current_p; 1537 1538 // We only get here (hopefully) if line[0] == '"' 1539 str = virp->vir_line + 1; 1540 1541 // If the line starts with "" this is the y_previous register. 1542 if (*str == '"') 1543 { 1544 set_prev = TRUE; 1545 str++; 1546 } 1547 1548 if (!ASCII_ISALNUM(*str) && *str != '-') 1549 { 1550 if (viminfo_error("E577: ", _("Illegal register name"), virp->vir_line)) 1551 return TRUE; // too many errors, pretend end-of-file 1552 do_it = FALSE; 1553 } 1554 get_yank_register(*str++, FALSE); 1555 y_current_p = get_y_current(); 1556 if (!force && y_current_p->y_array != NULL) 1557 do_it = FALSE; 1558 1559 if (*str == '@') 1560 { 1561 // "x@: register x used for @@ 1562 if (force || get_execreg_lastc() == NUL) 1563 set_execreg_lastc(str[-1]); 1564 } 1565 1566 size = 0; 1567 limit = 100; // Optimized for registers containing <= 100 lines 1568 if (do_it) 1569 { 1570 // Build the new register in array[]. 1571 // y_array is kept as-is until done. 1572 // The "do_it" flag is reset when something is wrong, in which case 1573 // array[] needs to be freed. 1574 if (set_prev) 1575 set_y_previous(y_current_p); 1576 array = ALLOC_MULT(char_u *, limit); 1577 str = skipwhite(skiptowhite(str)); 1578 if (STRNCMP(str, "CHAR", 4) == 0) 1579 new_type = MCHAR; 1580 else if (STRNCMP(str, "BLOCK", 5) == 0) 1581 new_type = MBLOCK; 1582 else 1583 new_type = MLINE; 1584 // get the block width; if it's missing we get a zero, which is OK 1585 str = skipwhite(skiptowhite(str)); 1586 new_width = getdigits(&str); 1587 } 1588 1589 while (!(eof = viminfo_readline(virp)) 1590 && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<')) 1591 { 1592 if (do_it) 1593 { 1594 if (size == limit) 1595 { 1596 char_u **new_array = (char_u **) 1597 alloc(limit * 2 * sizeof(char_u *)); 1598 1599 if (new_array == NULL) 1600 { 1601 do_it = FALSE; 1602 break; 1603 } 1604 for (i = 0; i < limit; i++) 1605 new_array[i] = array[i]; 1606 vim_free(array); 1607 array = new_array; 1608 limit *= 2; 1609 } 1610 str = viminfo_readstring(virp, 1, TRUE); 1611 if (str != NULL) 1612 array[size++] = str; 1613 else 1614 // error, don't store the result 1615 do_it = FALSE; 1616 } 1617 } 1618 1619 if (do_it) 1620 { 1621 // free y_array[] 1622 for (i = 0; i < y_current_p->y_size; i++) 1623 vim_free(y_current_p->y_array[i]); 1624 vim_free(y_current_p->y_array); 1625 1626 y_current_p->y_type = new_type; 1627 y_current_p->y_width = new_width; 1628 y_current_p->y_size = size; 1629 y_current_p->y_time_set = 0; 1630 if (size == 0) 1631 { 1632 y_current_p->y_array = NULL; 1633 } 1634 else 1635 { 1636 // Move the lines from array[] to y_array[]. 1637 y_current_p->y_array = ALLOC_MULT(char_u *, size); 1638 for (i = 0; i < size; i++) 1639 { 1640 if (y_current_p->y_array == NULL) 1641 vim_free(array[i]); 1642 else 1643 y_current_p->y_array[i] = array[i]; 1644 } 1645 } 1646 } 1647 else 1648 { 1649 // Free array[] if it was filled. 1650 for (i = 0; i < size; i++) 1651 vim_free(array[i]); 1652 } 1653 vim_free(array); 1654 1655 return eof; 1656 } 1657 1658 /* 1659 * Accept a new style register line from the viminfo, store it when it's new. 1660 */ 1661 static void 1662 handle_viminfo_register(garray_T *values, int force) 1663 { 1664 bval_T *vp = (bval_T *)values->ga_data; 1665 int flags; 1666 int name; 1667 int type; 1668 int linecount; 1669 int width; 1670 time_t timestamp; 1671 yankreg_T *y_ptr; 1672 yankreg_T *y_regs_p = get_y_regs(); 1673 int i; 1674 1675 // Check the format: 1676 // |{bartype},{flags},{name},{type}, 1677 // {linecount},{width},{timestamp},"line1","line2" 1678 if (values->ga_len < 6 1679 || vp[0].bv_type != BVAL_NR 1680 || vp[1].bv_type != BVAL_NR 1681 || vp[2].bv_type != BVAL_NR 1682 || vp[3].bv_type != BVAL_NR 1683 || vp[4].bv_type != BVAL_NR 1684 || vp[5].bv_type != BVAL_NR) 1685 return; 1686 flags = vp[0].bv_nr; 1687 name = vp[1].bv_nr; 1688 if (name < 0 || name >= NUM_REGISTERS) 1689 return; 1690 type = vp[2].bv_nr; 1691 if (type != MCHAR && type != MLINE && type != MBLOCK) 1692 return; 1693 linecount = vp[3].bv_nr; 1694 if (values->ga_len < 6 + linecount) 1695 return; 1696 width = vp[4].bv_nr; 1697 if (width < 0) 1698 return; 1699 1700 if (y_read_regs != NULL) 1701 // Reading viminfo for merging and writing. Store the register 1702 // content, don't update the current registers. 1703 y_ptr = &y_read_regs[name]; 1704 else 1705 y_ptr = &y_regs_p[name]; 1706 1707 // Do not overwrite unless forced or the timestamp is newer. 1708 timestamp = (time_t)vp[5].bv_nr; 1709 if (y_ptr->y_array != NULL && !force 1710 && (timestamp == 0 || y_ptr->y_time_set > timestamp)) 1711 return; 1712 1713 if (y_ptr->y_array != NULL) 1714 for (i = 0; i < y_ptr->y_size; i++) 1715 vim_free(y_ptr->y_array[i]); 1716 vim_free(y_ptr->y_array); 1717 1718 if (y_read_regs == NULL) 1719 { 1720 if (flags & REG_PREVIOUS) 1721 set_y_previous(y_ptr); 1722 if ((flags & REG_EXEC) && (force || get_execreg_lastc() == NUL)) 1723 set_execreg_lastc(get_register_name(name)); 1724 } 1725 y_ptr->y_type = type; 1726 y_ptr->y_width = width; 1727 y_ptr->y_size = linecount; 1728 y_ptr->y_time_set = timestamp; 1729 if (linecount == 0) 1730 { 1731 y_ptr->y_array = NULL; 1732 return; 1733 } 1734 y_ptr->y_array = ALLOC_MULT(char_u *, linecount); 1735 if (y_ptr->y_array == NULL) 1736 { 1737 y_ptr->y_size = 0; // ensure object state is consistent 1738 return; 1739 } 1740 for (i = 0; i < linecount; i++) 1741 { 1742 if (vp[i + 6].bv_allocated) 1743 { 1744 y_ptr->y_array[i] = vp[i + 6].bv_string; 1745 vp[i + 6].bv_string = NULL; 1746 } 1747 else 1748 y_ptr->y_array[i] = vim_strsave(vp[i + 6].bv_string); 1749 } 1750 } 1751 1752 static void 1753 write_viminfo_registers(FILE *fp) 1754 { 1755 int i, j; 1756 char_u *type; 1757 char_u c; 1758 int num_lines; 1759 int max_num_lines; 1760 int max_kbyte; 1761 long len; 1762 yankreg_T *y_ptr; 1763 yankreg_T *y_regs_p = get_y_regs();; 1764 1765 fputs(_("\n# Registers:\n"), fp); 1766 1767 // Get '<' value, use old '"' value if '<' is not found. 1768 max_num_lines = get_viminfo_parameter('<'); 1769 if (max_num_lines < 0) 1770 max_num_lines = get_viminfo_parameter('"'); 1771 if (max_num_lines == 0) 1772 return; 1773 max_kbyte = get_viminfo_parameter('s'); 1774 if (max_kbyte == 0) 1775 return; 1776 1777 for (i = 0; i < NUM_REGISTERS; i++) 1778 { 1779 #ifdef FEAT_CLIPBOARD 1780 // Skip '*'/'+' register, we don't want them back next time 1781 if (i == STAR_REGISTER || i == PLUS_REGISTER) 1782 continue; 1783 #endif 1784 #ifdef FEAT_DND 1785 // Neither do we want the '~' register 1786 if (i == TILDE_REGISTER) 1787 continue; 1788 #endif 1789 // When reading viminfo for merging and writing: Use the register from 1790 // viminfo if it's newer. 1791 if (y_read_regs != NULL 1792 && y_read_regs[i].y_array != NULL 1793 && (y_regs_p[i].y_array == NULL || 1794 y_read_regs[i].y_time_set > y_regs_p[i].y_time_set)) 1795 y_ptr = &y_read_regs[i]; 1796 else if (y_regs_p[i].y_array == NULL) 1797 continue; 1798 else 1799 y_ptr = &y_regs_p[i]; 1800 1801 // Skip empty registers. 1802 num_lines = y_ptr->y_size; 1803 if (num_lines == 0 1804 || (num_lines == 1 && y_ptr->y_type == MCHAR 1805 && *y_ptr->y_array[0] == NUL)) 1806 continue; 1807 1808 if (max_kbyte > 0) 1809 { 1810 // Skip register if there is more text than the maximum size. 1811 len = 0; 1812 for (j = 0; j < num_lines; j++) 1813 len += (long)STRLEN(y_ptr->y_array[j]) + 1L; 1814 if (len > (long)max_kbyte * 1024L) 1815 continue; 1816 } 1817 1818 switch (y_ptr->y_type) 1819 { 1820 case MLINE: 1821 type = (char_u *)"LINE"; 1822 break; 1823 case MCHAR: 1824 type = (char_u *)"CHAR"; 1825 break; 1826 case MBLOCK: 1827 type = (char_u *)"BLOCK"; 1828 break; 1829 default: 1830 semsg(_("E574: Unknown register type %d"), y_ptr->y_type); 1831 type = (char_u *)"LINE"; 1832 break; 1833 } 1834 if (get_y_previous() == &y_regs_p[i]) 1835 fprintf(fp, "\""); 1836 c = get_register_name(i); 1837 fprintf(fp, "\"%c", c); 1838 if (c == get_execreg_lastc()) 1839 fprintf(fp, "@"); 1840 fprintf(fp, "\t%s\t%d\n", type, (int)y_ptr->y_width); 1841 1842 // If max_num_lines < 0, then we save ALL the lines in the register 1843 if (max_num_lines > 0 && num_lines > max_num_lines) 1844 num_lines = max_num_lines; 1845 for (j = 0; j < num_lines; j++) 1846 { 1847 putc('\t', fp); 1848 viminfo_writestring(fp, y_ptr->y_array[j]); 1849 } 1850 1851 { 1852 int flags = 0; 1853 int remaining; 1854 1855 // New style with a bar line. Format: 1856 // |{bartype},{flags},{name},{type}, 1857 // {linecount},{width},{timestamp},"line1","line2" 1858 // flags: REG_PREVIOUS - register is y_previous 1859 // REG_EXEC - used for @@ 1860 if (get_y_previous() == &y_regs_p[i]) 1861 flags |= REG_PREVIOUS; 1862 if (c == get_execreg_lastc()) 1863 flags |= REG_EXEC; 1864 fprintf(fp, "|%d,%d,%d,%d,%d,%d,%ld", BARTYPE_REGISTER, flags, 1865 i, y_ptr->y_type, num_lines, (int)y_ptr->y_width, 1866 (long)y_ptr->y_time_set); 1867 // 11 chars for type/flags/name/type, 3 * 20 for numbers 1868 remaining = LSIZE - 71; 1869 for (j = 0; j < num_lines; j++) 1870 { 1871 putc(',', fp); 1872 --remaining; 1873 remaining = barline_writestring(fp, y_ptr->y_array[j], 1874 remaining); 1875 } 1876 putc('\n', fp); 1877 } 1878 } 1879 } 1880 1881 /* 1882 * Functions relating to reading/writing marks from viminfo 1883 */ 1884 1885 static xfmark_T *vi_namedfm = NULL; 1886 #ifdef FEAT_JUMPLIST 1887 static xfmark_T *vi_jumplist = NULL; 1888 static int vi_jumplist_len = 0; 1889 #endif 1890 1891 static void 1892 write_one_mark(FILE *fp_out, int c, pos_T *pos) 1893 { 1894 if (pos->lnum != 0) 1895 fprintf(fp_out, "\t%c\t%ld\t%d\n", c, (long)pos->lnum, (int)pos->col); 1896 } 1897 1898 static void 1899 write_buffer_marks(buf_T *buf, FILE *fp_out) 1900 { 1901 int i; 1902 pos_T pos; 1903 1904 home_replace(NULL, buf->b_ffname, IObuff, IOSIZE, TRUE); 1905 fprintf(fp_out, "\n> "); 1906 viminfo_writestring(fp_out, IObuff); 1907 1908 // Write the last used timestamp as the lnum of the non-existing mark '*'. 1909 // Older Vims will ignore it and/or copy it. 1910 pos.lnum = (linenr_T)buf->b_last_used; 1911 pos.col = 0; 1912 write_one_mark(fp_out, '*', &pos); 1913 1914 write_one_mark(fp_out, '"', &buf->b_last_cursor); 1915 write_one_mark(fp_out, '^', &buf->b_last_insert); 1916 write_one_mark(fp_out, '.', &buf->b_last_change); 1917 #ifdef FEAT_JUMPLIST 1918 // changelist positions are stored oldest first 1919 for (i = 0; i < buf->b_changelistlen; ++i) 1920 { 1921 // skip duplicates 1922 if (i == 0 || !EQUAL_POS(buf->b_changelist[i - 1], 1923 buf->b_changelist[i])) 1924 write_one_mark(fp_out, '+', &buf->b_changelist[i]); 1925 } 1926 #endif 1927 for (i = 0; i < NMARKS; i++) 1928 write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]); 1929 } 1930 1931 /* 1932 * Return TRUE if marks for "buf" should not be written. 1933 */ 1934 static int 1935 skip_for_viminfo(buf_T *buf) 1936 { 1937 return 1938 #ifdef FEAT_TERMINAL 1939 bt_terminal(buf) || 1940 #endif 1941 removable(buf->b_ffname); 1942 } 1943 1944 /* 1945 * Write all the named marks for all buffers. 1946 * When "buflist" is not NULL fill it with the buffers for which marks are to 1947 * be written. 1948 */ 1949 static void 1950 write_viminfo_marks(FILE *fp_out, garray_T *buflist) 1951 { 1952 buf_T *buf; 1953 int is_mark_set; 1954 int i; 1955 win_T *win; 1956 tabpage_T *tp; 1957 1958 // Set b_last_cursor for the all buffers that have a window. 1959 FOR_ALL_TAB_WINDOWS(tp, win) 1960 set_last_cursor(win); 1961 1962 fputs(_("\n# History of marks within files (newest to oldest):\n"), fp_out); 1963 FOR_ALL_BUFFERS(buf) 1964 { 1965 // Only write something if buffer has been loaded and at least one 1966 // mark is set. 1967 if (buf->b_marks_read) 1968 { 1969 if (buf->b_last_cursor.lnum != 0) 1970 is_mark_set = TRUE; 1971 else 1972 { 1973 is_mark_set = FALSE; 1974 for (i = 0; i < NMARKS; i++) 1975 if (buf->b_namedm[i].lnum != 0) 1976 { 1977 is_mark_set = TRUE; 1978 break; 1979 } 1980 } 1981 if (is_mark_set && buf->b_ffname != NULL 1982 && buf->b_ffname[0] != NUL 1983 && !skip_for_viminfo(buf)) 1984 { 1985 if (buflist == NULL) 1986 write_buffer_marks(buf, fp_out); 1987 else if (ga_grow(buflist, 1) == OK) 1988 ((buf_T **)buflist->ga_data)[buflist->ga_len++] = buf; 1989 } 1990 } 1991 } 1992 } 1993 1994 static void 1995 write_one_filemark( 1996 FILE *fp, 1997 xfmark_T *fm, 1998 int c1, 1999 int c2) 2000 { 2001 char_u *name; 2002 2003 if (fm->fmark.mark.lnum == 0) // not set 2004 return; 2005 2006 if (fm->fmark.fnum != 0) // there is a buffer 2007 name = buflist_nr2name(fm->fmark.fnum, TRUE, FALSE); 2008 else 2009 name = fm->fname; // use name from .viminfo 2010 if (name != NULL && *name != NUL) 2011 { 2012 fprintf(fp, "%c%c %ld %ld ", c1, c2, (long)fm->fmark.mark.lnum, 2013 (long)fm->fmark.mark.col); 2014 viminfo_writestring(fp, name); 2015 2016 // Barline: |{bartype},{name},{lnum},{col},{timestamp},{filename} 2017 // size up to filename: 8 + 3 * 20 2018 fprintf(fp, "|%d,%d,%ld,%ld,%ld,", BARTYPE_MARK, c2, 2019 (long)fm->fmark.mark.lnum, (long)fm->fmark.mark.col, 2020 (long)fm->time_set); 2021 barline_writestring(fp, name, LSIZE - 70); 2022 putc('\n', fp); 2023 } 2024 2025 if (fm->fmark.fnum != 0) 2026 vim_free(name); 2027 } 2028 2029 static void 2030 write_viminfo_filemarks(FILE *fp) 2031 { 2032 int i; 2033 char_u *name; 2034 buf_T *buf; 2035 xfmark_T *namedfm_p = get_namedfm(); 2036 xfmark_T *fm; 2037 int vi_idx; 2038 int idx; 2039 2040 if (get_viminfo_parameter('f') == 0) 2041 return; 2042 2043 fputs(_("\n# File marks:\n"), fp); 2044 2045 // Write the filemarks 'A - 'Z 2046 for (i = 0; i < NMARKS; i++) 2047 { 2048 if (vi_namedfm != NULL 2049 && (vi_namedfm[i].time_set > namedfm_p[i].time_set 2050 || namedfm_p[i].fmark.mark.lnum == 0)) 2051 fm = &vi_namedfm[i]; 2052 else 2053 fm = &namedfm_p[i]; 2054 write_one_filemark(fp, fm, '\'', i + 'A'); 2055 } 2056 2057 // Find a mark that is the same file and position as the cursor. 2058 // That one, or else the last one is deleted. 2059 // Move '0 to '1, '1 to '2, etc. until the matching one or '9 2060 // Set the '0 mark to current cursor position. 2061 if (curbuf->b_ffname != NULL && !skip_for_viminfo(curbuf)) 2062 { 2063 name = buflist_nr2name(curbuf->b_fnum, TRUE, FALSE); 2064 for (i = NMARKS; i < NMARKS + EXTRA_MARKS - 1; ++i) 2065 if (namedfm_p[i].fmark.mark.lnum == curwin->w_cursor.lnum 2066 && (namedfm_p[i].fname == NULL 2067 ? namedfm_p[i].fmark.fnum == curbuf->b_fnum 2068 : (name != NULL 2069 && STRCMP(name, namedfm_p[i].fname) == 0))) 2070 break; 2071 vim_free(name); 2072 2073 vim_free(namedfm_p[i].fname); 2074 for ( ; i > NMARKS; --i) 2075 namedfm_p[i] = namedfm_p[i - 1]; 2076 namedfm_p[NMARKS].fmark.mark = curwin->w_cursor; 2077 namedfm_p[NMARKS].fmark.fnum = curbuf->b_fnum; 2078 namedfm_p[NMARKS].fname = NULL; 2079 namedfm_p[NMARKS].time_set = vim_time(); 2080 } 2081 2082 // Write the filemarks '0 - '9. Newest (highest timestamp) first. 2083 vi_idx = NMARKS; 2084 idx = NMARKS; 2085 for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++) 2086 { 2087 xfmark_T *vi_fm = vi_namedfm != NULL ? &vi_namedfm[vi_idx] : NULL; 2088 2089 if (vi_fm != NULL 2090 && vi_fm->fmark.mark.lnum != 0 2091 && (vi_fm->time_set > namedfm_p[idx].time_set 2092 || namedfm_p[idx].fmark.mark.lnum == 0)) 2093 { 2094 fm = vi_fm; 2095 ++vi_idx; 2096 } 2097 else 2098 { 2099 fm = &namedfm_p[idx++]; 2100 if (vi_fm != NULL 2101 && vi_fm->fmark.mark.lnum == fm->fmark.mark.lnum 2102 && vi_fm->time_set == fm->time_set 2103 && ((vi_fm->fmark.fnum != 0 2104 && vi_fm->fmark.fnum == fm->fmark.fnum) 2105 || (vi_fm->fname != NULL 2106 && fm->fname != NULL 2107 && STRCMP(vi_fm->fname, fm->fname) == 0))) 2108 ++vi_idx; // skip duplicate 2109 } 2110 write_one_filemark(fp, fm, '\'', i - NMARKS + '0'); 2111 } 2112 2113 #ifdef FEAT_JUMPLIST 2114 // Write the jumplist with -' 2115 fputs(_("\n# Jumplist (newest first):\n"), fp); 2116 setpcmark(); // add current cursor position 2117 cleanup_jumplist(curwin, FALSE); 2118 vi_idx = 0; 2119 idx = curwin->w_jumplistlen - 1; 2120 for (i = 0; i < JUMPLISTSIZE; ++i) 2121 { 2122 xfmark_T *vi_fm; 2123 2124 fm = idx >= 0 ? &curwin->w_jumplist[idx] : NULL; 2125 vi_fm = vi_idx < vi_jumplist_len ? &vi_jumplist[vi_idx] : NULL; 2126 if (fm == NULL && vi_fm == NULL) 2127 break; 2128 if (fm == NULL || (vi_fm != NULL && fm->time_set < vi_fm->time_set)) 2129 { 2130 fm = vi_fm; 2131 ++vi_idx; 2132 } 2133 else 2134 --idx; 2135 if (fm->fmark.fnum == 0 2136 || ((buf = buflist_findnr(fm->fmark.fnum)) != NULL 2137 && !skip_for_viminfo(buf))) 2138 write_one_filemark(fp, fm, '-', '\''); 2139 } 2140 #endif 2141 } 2142 2143 /* 2144 * Compare functions for qsort() below, that compares b_last_used. 2145 */ 2146 static int 2147 buf_compare(const void *s1, const void *s2) 2148 { 2149 buf_T *buf1 = *(buf_T **)s1; 2150 buf_T *buf2 = *(buf_T **)s2; 2151 2152 if (buf1->b_last_used == buf2->b_last_used) 2153 return 0; 2154 return buf1->b_last_used > buf2->b_last_used ? -1 : 1; 2155 } 2156 2157 /* 2158 * Handle marks in the viminfo file: 2159 * fp_out != NULL: copy marks, in time order with buffers in "buflist". 2160 * fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only 2161 * fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles 2162 */ 2163 static void 2164 copy_viminfo_marks( 2165 vir_T *virp, 2166 FILE *fp_out, 2167 garray_T *buflist, 2168 int eof, 2169 int flags) 2170 { 2171 char_u *line = virp->vir_line; 2172 buf_T *buf; 2173 int num_marked_files; 2174 int load_marks; 2175 int copy_marks_out; 2176 char_u *str; 2177 int i; 2178 char_u *p; 2179 char_u *name_buf; 2180 pos_T pos; 2181 #ifdef FEAT_EVAL 2182 list_T *list = NULL; 2183 #endif 2184 int count = 0; 2185 int buflist_used = 0; 2186 buf_T *buflist_buf = NULL; 2187 2188 if ((name_buf = alloc(LSIZE)) == NULL) 2189 return; 2190 *name_buf = NUL; 2191 2192 if (fp_out != NULL && buflist->ga_len > 0) 2193 { 2194 // Sort the list of buffers on b_last_used. 2195 qsort(buflist->ga_data, (size_t)buflist->ga_len, 2196 sizeof(buf_T *), buf_compare); 2197 buflist_buf = ((buf_T **)buflist->ga_data)[0]; 2198 } 2199 2200 #ifdef FEAT_EVAL 2201 if (fp_out == NULL && (flags & (VIF_GET_OLDFILES | VIF_FORCEIT))) 2202 { 2203 list = list_alloc(); 2204 if (list != NULL) 2205 set_vim_var_list(VV_OLDFILES, list); 2206 } 2207 #endif 2208 2209 num_marked_files = get_viminfo_parameter('\''); 2210 while (!eof && (count < num_marked_files || fp_out == NULL)) 2211 { 2212 if (line[0] != '>') 2213 { 2214 if (line[0] != '\n' && line[0] != '\r' && line[0] != '#') 2215 { 2216 if (viminfo_error("E576: ", _("Missing '>'"), line)) 2217 break; // too many errors, return now 2218 } 2219 eof = vim_fgets(line, LSIZE, virp->vir_fd); 2220 continue; // Skip this dud line 2221 } 2222 2223 // Handle long line and translate escaped characters. 2224 // Find file name, set str to start. 2225 // Ignore leading and trailing white space. 2226 str = skipwhite(line + 1); 2227 str = viminfo_readstring(virp, (int)(str - virp->vir_line), FALSE); 2228 if (str == NULL) 2229 continue; 2230 p = str + STRLEN(str); 2231 while (p != str && (*p == NUL || vim_isspace(*p))) 2232 p--; 2233 if (*p) 2234 p++; 2235 *p = NUL; 2236 2237 #ifdef FEAT_EVAL 2238 if (list != NULL) 2239 list_append_string(list, str, -1); 2240 #endif 2241 2242 // If fp_out == NULL, load marks for current buffer. 2243 // If fp_out != NULL, copy marks for buffers not in buflist. 2244 load_marks = copy_marks_out = FALSE; 2245 if (fp_out == NULL) 2246 { 2247 if ((flags & VIF_WANT_MARKS) && curbuf->b_ffname != NULL) 2248 { 2249 if (*name_buf == NUL) // only need to do this once 2250 home_replace(NULL, curbuf->b_ffname, name_buf, LSIZE, TRUE); 2251 if (fnamecmp(str, name_buf) == 0) 2252 load_marks = TRUE; 2253 } 2254 } 2255 else // fp_out != NULL 2256 { 2257 // This is slow if there are many buffers!! 2258 FOR_ALL_BUFFERS(buf) 2259 if (buf->b_ffname != NULL) 2260 { 2261 home_replace(NULL, buf->b_ffname, name_buf, LSIZE, TRUE); 2262 if (fnamecmp(str, name_buf) == 0) 2263 break; 2264 } 2265 2266 // Copy marks if the buffer has not been loaded. 2267 if (buf == NULL || !buf->b_marks_read) 2268 { 2269 int did_read_line = FALSE; 2270 2271 if (buflist_buf != NULL) 2272 { 2273 // Read the next line. If it has the "*" mark compare the 2274 // time stamps. Write entries from "buflist" that are 2275 // newer. 2276 if (!(eof = viminfo_readline(virp)) && line[0] == TAB) 2277 { 2278 did_read_line = TRUE; 2279 if (line[1] == '*') 2280 { 2281 long ltime; 2282 2283 sscanf((char *)line + 2, "%ld ", <ime); 2284 while ((time_T)ltime < buflist_buf->b_last_used) 2285 { 2286 write_buffer_marks(buflist_buf, fp_out); 2287 if (++count >= num_marked_files) 2288 break; 2289 if (++buflist_used == buflist->ga_len) 2290 { 2291 buflist_buf = NULL; 2292 break; 2293 } 2294 buflist_buf = 2295 ((buf_T **)buflist->ga_data)[buflist_used]; 2296 } 2297 } 2298 else 2299 { 2300 // No timestamp, must be written by an older Vim. 2301 // Assume all remaining buffers are older then 2302 // ours. 2303 while (count < num_marked_files 2304 && buflist_used < buflist->ga_len) 2305 { 2306 buflist_buf = ((buf_T **)buflist->ga_data) 2307 [buflist_used++]; 2308 write_buffer_marks(buflist_buf, fp_out); 2309 ++count; 2310 } 2311 buflist_buf = NULL; 2312 } 2313 2314 if (count >= num_marked_files) 2315 { 2316 vim_free(str); 2317 break; 2318 } 2319 } 2320 } 2321 2322 fputs("\n> ", fp_out); 2323 viminfo_writestring(fp_out, str); 2324 if (did_read_line) 2325 fputs((char *)line, fp_out); 2326 2327 count++; 2328 copy_marks_out = TRUE; 2329 } 2330 } 2331 vim_free(str); 2332 2333 pos.coladd = 0; 2334 while (!(eof = viminfo_readline(virp)) && line[0] == TAB) 2335 { 2336 if (load_marks) 2337 { 2338 if (line[1] != NUL) 2339 { 2340 unsigned u; 2341 2342 sscanf((char *)line + 2, "%ld %u", &pos.lnum, &u); 2343 pos.col = u; 2344 switch (line[1]) 2345 { 2346 case '"': curbuf->b_last_cursor = pos; break; 2347 case '^': curbuf->b_last_insert = pos; break; 2348 case '.': curbuf->b_last_change = pos; break; 2349 case '+': 2350 #ifdef FEAT_JUMPLIST 2351 // changelist positions are stored oldest 2352 // first 2353 if (curbuf->b_changelistlen == JUMPLISTSIZE) 2354 // list is full, remove oldest entry 2355 mch_memmove(curbuf->b_changelist, 2356 curbuf->b_changelist + 1, 2357 sizeof(pos_T) * (JUMPLISTSIZE - 1)); 2358 else 2359 ++curbuf->b_changelistlen; 2360 curbuf->b_changelist[ 2361 curbuf->b_changelistlen - 1] = pos; 2362 #endif 2363 break; 2364 2365 // Using the line number for the last-used 2366 // timestamp. 2367 case '*': curbuf->b_last_used = pos.lnum; break; 2368 2369 default: if ((i = line[1] - 'a') >= 0 && i < NMARKS) 2370 curbuf->b_namedm[i] = pos; 2371 } 2372 } 2373 } 2374 else if (copy_marks_out) 2375 fputs((char *)line, fp_out); 2376 } 2377 2378 if (load_marks) 2379 { 2380 #ifdef FEAT_JUMPLIST 2381 win_T *wp; 2382 2383 FOR_ALL_WINDOWS(wp) 2384 { 2385 if (wp->w_buffer == curbuf) 2386 wp->w_changelistidx = curbuf->b_changelistlen; 2387 } 2388 #endif 2389 break; 2390 } 2391 } 2392 2393 if (fp_out != NULL) 2394 // Write any remaining entries from buflist. 2395 while (count < num_marked_files && buflist_used < buflist->ga_len) 2396 { 2397 buflist_buf = ((buf_T **)buflist->ga_data)[buflist_used++]; 2398 write_buffer_marks(buflist_buf, fp_out); 2399 ++count; 2400 } 2401 2402 vim_free(name_buf); 2403 } 2404 2405 /* 2406 * Read marks for the current buffer from the viminfo file, when we support 2407 * buffer marks and the buffer has a name. 2408 */ 2409 void 2410 check_marks_read(void) 2411 { 2412 if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0 2413 && curbuf->b_ffname != NULL) 2414 read_viminfo(NULL, VIF_WANT_MARKS); 2415 2416 // Always set b_marks_read; needed when 'viminfo' is changed to include 2417 // the ' parameter after opening a buffer. 2418 curbuf->b_marks_read = TRUE; 2419 } 2420 2421 static int 2422 read_viminfo_filemark(vir_T *virp, int force) 2423 { 2424 char_u *str; 2425 xfmark_T *namedfm_p = get_namedfm(); 2426 xfmark_T *fm; 2427 int i; 2428 2429 // We only get here if line[0] == '\'' or '-'. 2430 // Illegal mark names are ignored (for future expansion). 2431 str = virp->vir_line + 1; 2432 if ( 2433 #ifndef EBCDIC 2434 *str <= 127 && 2435 #endif 2436 ((*virp->vir_line == '\'' && (VIM_ISDIGIT(*str) || isupper(*str))) 2437 || (*virp->vir_line == '-' && *str == '\''))) 2438 { 2439 if (*str == '\'') 2440 { 2441 #ifdef FEAT_JUMPLIST 2442 // If the jumplist isn't full insert fmark as oldest entry 2443 if (curwin->w_jumplistlen == JUMPLISTSIZE) 2444 fm = NULL; 2445 else 2446 { 2447 for (i = curwin->w_jumplistlen; i > 0; --i) 2448 curwin->w_jumplist[i] = curwin->w_jumplist[i - 1]; 2449 ++curwin->w_jumplistidx; 2450 ++curwin->w_jumplistlen; 2451 fm = &curwin->w_jumplist[0]; 2452 fm->fmark.mark.lnum = 0; 2453 fm->fname = NULL; 2454 } 2455 #else 2456 fm = NULL; 2457 #endif 2458 } 2459 else if (VIM_ISDIGIT(*str)) 2460 fm = &namedfm_p[*str - '0' + NMARKS]; 2461 else 2462 fm = &namedfm_p[*str - 'A']; 2463 if (fm != NULL && (fm->fmark.mark.lnum == 0 || force)) 2464 { 2465 str = skipwhite(str + 1); 2466 fm->fmark.mark.lnum = getdigits(&str); 2467 str = skipwhite(str); 2468 fm->fmark.mark.col = getdigits(&str); 2469 fm->fmark.mark.coladd = 0; 2470 fm->fmark.fnum = 0; 2471 str = skipwhite(str); 2472 vim_free(fm->fname); 2473 fm->fname = viminfo_readstring(virp, (int)(str - virp->vir_line), 2474 FALSE); 2475 fm->time_set = 0; 2476 } 2477 } 2478 return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd); 2479 } 2480 2481 /* 2482 * Prepare for reading viminfo marks when writing viminfo later. 2483 */ 2484 static void 2485 prepare_viminfo_marks(void) 2486 { 2487 vi_namedfm = ALLOC_CLEAR_MULT(xfmark_T, NMARKS + EXTRA_MARKS); 2488 #ifdef FEAT_JUMPLIST 2489 vi_jumplist = ALLOC_CLEAR_MULT(xfmark_T, JUMPLISTSIZE); 2490 vi_jumplist_len = 0; 2491 #endif 2492 } 2493 2494 static void 2495 finish_viminfo_marks(void) 2496 { 2497 int i; 2498 2499 if (vi_namedfm != NULL) 2500 { 2501 for (i = 0; i < NMARKS + EXTRA_MARKS; ++i) 2502 vim_free(vi_namedfm[i].fname); 2503 VIM_CLEAR(vi_namedfm); 2504 } 2505 #ifdef FEAT_JUMPLIST 2506 if (vi_jumplist != NULL) 2507 { 2508 for (i = 0; i < vi_jumplist_len; ++i) 2509 vim_free(vi_jumplist[i].fname); 2510 VIM_CLEAR(vi_jumplist); 2511 } 2512 #endif 2513 } 2514 2515 /* 2516 * Accept a new style mark line from the viminfo, store it when it's new. 2517 */ 2518 static void 2519 handle_viminfo_mark(garray_T *values, int force) 2520 { 2521 bval_T *vp = (bval_T *)values->ga_data; 2522 int name; 2523 linenr_T lnum; 2524 colnr_T col; 2525 time_t timestamp; 2526 xfmark_T *fm = NULL; 2527 2528 // Check the format: 2529 // |{bartype},{name},{lnum},{col},{timestamp},{filename} 2530 if (values->ga_len < 5 2531 || vp[0].bv_type != BVAL_NR 2532 || vp[1].bv_type != BVAL_NR 2533 || vp[2].bv_type != BVAL_NR 2534 || vp[3].bv_type != BVAL_NR 2535 || vp[4].bv_type != BVAL_STRING) 2536 return; 2537 2538 name = vp[0].bv_nr; 2539 if (name != '\'' && !VIM_ISDIGIT(name) && !ASCII_ISUPPER(name)) 2540 return; 2541 lnum = vp[1].bv_nr; 2542 col = vp[2].bv_nr; 2543 if (lnum <= 0 || col < 0) 2544 return; 2545 timestamp = (time_t)vp[3].bv_nr; 2546 2547 if (name == '\'') 2548 { 2549 #ifdef FEAT_JUMPLIST 2550 if (vi_jumplist != NULL) 2551 { 2552 if (vi_jumplist_len < JUMPLISTSIZE) 2553 fm = &vi_jumplist[vi_jumplist_len++]; 2554 } 2555 else 2556 { 2557 int idx; 2558 int i; 2559 2560 // If we have a timestamp insert it in the right place. 2561 if (timestamp != 0) 2562 { 2563 for (idx = curwin->w_jumplistlen - 1; idx >= 0; --idx) 2564 if (curwin->w_jumplist[idx].time_set < timestamp) 2565 { 2566 ++idx; 2567 break; 2568 } 2569 // idx cannot be zero now 2570 if (idx < 0 && curwin->w_jumplistlen < JUMPLISTSIZE) 2571 // insert as the oldest entry 2572 idx = 0; 2573 } 2574 else if (curwin->w_jumplistlen < JUMPLISTSIZE) 2575 // insert as oldest entry 2576 idx = 0; 2577 else 2578 idx = -1; 2579 2580 if (idx >= 0) 2581 { 2582 if (curwin->w_jumplistlen == JUMPLISTSIZE) 2583 { 2584 // Drop the oldest entry. 2585 --idx; 2586 vim_free(curwin->w_jumplist[0].fname); 2587 for (i = 0; i < idx; ++i) 2588 curwin->w_jumplist[i] = curwin->w_jumplist[i + 1]; 2589 } 2590 else 2591 { 2592 // Move newer entries forward. 2593 for (i = curwin->w_jumplistlen; i > idx; --i) 2594 curwin->w_jumplist[i] = curwin->w_jumplist[i - 1]; 2595 ++curwin->w_jumplistidx; 2596 ++curwin->w_jumplistlen; 2597 } 2598 fm = &curwin->w_jumplist[idx]; 2599 fm->fmark.mark.lnum = 0; 2600 fm->fname = NULL; 2601 fm->time_set = 0; 2602 } 2603 } 2604 #endif 2605 } 2606 else 2607 { 2608 int idx; 2609 xfmark_T *namedfm_p = get_namedfm(); 2610 2611 if (VIM_ISDIGIT(name)) 2612 { 2613 if (vi_namedfm != NULL) 2614 idx = name - '0' + NMARKS; 2615 else 2616 { 2617 int i; 2618 2619 // Do not use the name from the viminfo file, insert in time 2620 // order. 2621 for (idx = NMARKS; idx < NMARKS + EXTRA_MARKS; ++idx) 2622 if (namedfm_p[idx].time_set < timestamp) 2623 break; 2624 if (idx == NMARKS + EXTRA_MARKS) 2625 // All existing entries are newer. 2626 return; 2627 i = NMARKS + EXTRA_MARKS - 1; 2628 2629 vim_free(namedfm_p[i].fname); 2630 for ( ; i > idx; --i) 2631 namedfm_p[i] = namedfm_p[i - 1]; 2632 namedfm_p[idx].fname = NULL; 2633 } 2634 } 2635 else 2636 idx = name - 'A'; 2637 if (vi_namedfm != NULL) 2638 fm = &vi_namedfm[idx]; 2639 else 2640 fm = &namedfm_p[idx]; 2641 } 2642 2643 if (fm != NULL) 2644 { 2645 if (vi_namedfm != NULL || fm->fmark.mark.lnum == 0 2646 || fm->time_set < timestamp || force) 2647 { 2648 fm->fmark.mark.lnum = lnum; 2649 fm->fmark.mark.col = col; 2650 fm->fmark.mark.coladd = 0; 2651 fm->fmark.fnum = 0; 2652 vim_free(fm->fname); 2653 if (vp[4].bv_allocated) 2654 { 2655 fm->fname = vp[4].bv_string; 2656 vp[4].bv_string = NULL; 2657 } 2658 else 2659 fm->fname = vim_strsave(vp[4].bv_string); 2660 fm->time_set = timestamp; 2661 } 2662 } 2663 } 2664 2665 static int 2666 read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing) 2667 { 2668 char_u *p = virp->vir_line + 1; 2669 int bartype; 2670 garray_T values; 2671 bval_T *vp; 2672 int i; 2673 int read_next = TRUE; 2674 2675 /* 2676 * The format is: |{bartype},{value},... 2677 * For a very long string: 2678 * |{bartype},>{length of "{text}{text2}"} 2679 * |<{text1} 2680 * |<{text2},{value} 2681 * For a long line not using a string 2682 * |{bartype},{lots of values},> 2683 * |<{value},{value} 2684 */ 2685 if (*p == '<') 2686 { 2687 // Continuation line of an unrecognized item. 2688 if (writing) 2689 ga_add_string(&virp->vir_barlines, virp->vir_line); 2690 } 2691 else 2692 { 2693 ga_init2(&values, sizeof(bval_T), 20); 2694 bartype = getdigits(&p); 2695 switch (bartype) 2696 { 2697 case BARTYPE_VERSION: 2698 // Only use the version when it comes before the encoding. 2699 // If it comes later it was copied by a Vim version that 2700 // doesn't understand the version. 2701 if (!got_encoding) 2702 { 2703 read_next = barline_parse(virp, p, &values); 2704 vp = (bval_T *)values.ga_data; 2705 if (values.ga_len > 0 && vp->bv_type == BVAL_NR) 2706 virp->vir_version = vp->bv_nr; 2707 } 2708 break; 2709 2710 case BARTYPE_HISTORY: 2711 read_next = barline_parse(virp, p, &values); 2712 handle_viminfo_history(&values, writing); 2713 break; 2714 2715 case BARTYPE_REGISTER: 2716 read_next = barline_parse(virp, p, &values); 2717 handle_viminfo_register(&values, force); 2718 break; 2719 2720 case BARTYPE_MARK: 2721 read_next = barline_parse(virp, p, &values); 2722 handle_viminfo_mark(&values, force); 2723 break; 2724 2725 default: 2726 // copy unrecognized line (for future use) 2727 if (writing) 2728 ga_add_string(&virp->vir_barlines, virp->vir_line); 2729 } 2730 for (i = 0; i < values.ga_len; ++i) 2731 { 2732 vp = (bval_T *)values.ga_data + i; 2733 if (vp->bv_type == BVAL_STRING && vp->bv_allocated) 2734 vim_free(vp->bv_string); 2735 } 2736 ga_clear(&values); 2737 } 2738 2739 if (read_next) 2740 return viminfo_readline(virp); 2741 return FALSE; 2742 } 2743 2744 /* 2745 * read_viminfo_up_to_marks() -- Only called from do_viminfo(). Reads in the 2746 * first part of the viminfo file which contains everything but the marks that 2747 * are local to a file. Returns TRUE when end-of-file is reached. -- webb 2748 */ 2749 static int 2750 read_viminfo_up_to_marks( 2751 vir_T *virp, 2752 int forceit, 2753 int writing) 2754 { 2755 int eof; 2756 buf_T *buf; 2757 int got_encoding = FALSE; 2758 2759 #ifdef FEAT_CMDHIST 2760 prepare_viminfo_history(forceit ? 9999 : 0, writing); 2761 #endif 2762 2763 eof = viminfo_readline(virp); 2764 while (!eof && virp->vir_line[0] != '>') 2765 { 2766 switch (virp->vir_line[0]) 2767 { 2768 // Characters reserved for future expansion, ignored now 2769 case '+': // "+40 /path/dir file", for running vim without args 2770 case '^': // to be defined 2771 case '<': // long line - ignored 2772 // A comment or empty line. 2773 case NUL: 2774 case '\r': 2775 case '\n': 2776 case '#': 2777 eof = viminfo_readline(virp); 2778 break; 2779 case '|': 2780 eof = read_viminfo_barline(virp, got_encoding, 2781 forceit, writing); 2782 break; 2783 case '*': // "*encoding=value" 2784 got_encoding = TRUE; 2785 eof = viminfo_encoding(virp); 2786 break; 2787 case '!': // global variable 2788 #ifdef FEAT_EVAL 2789 eof = read_viminfo_varlist(virp, writing); 2790 #else 2791 eof = viminfo_readline(virp); 2792 #endif 2793 break; 2794 case '%': // entry for buffer list 2795 eof = read_viminfo_bufferlist(virp, writing); 2796 break; 2797 case '"': 2798 // When registers are in bar lines skip the old style register 2799 // lines. 2800 if (virp->vir_version < VIMINFO_VERSION_WITH_REGISTERS) 2801 eof = read_viminfo_register(virp, forceit); 2802 else 2803 do { 2804 eof = viminfo_readline(virp); 2805 } while (!eof && (virp->vir_line[0] == TAB 2806 || virp->vir_line[0] == '<')); 2807 break; 2808 case '/': // Search string 2809 case '&': // Substitute search string 2810 case '~': // Last search string, followed by '/' or '&' 2811 eof = read_viminfo_search_pattern(virp, forceit); 2812 break; 2813 case '$': 2814 eof = read_viminfo_sub_string(virp, forceit); 2815 break; 2816 case ':': 2817 case '?': 2818 case '=': 2819 case '@': 2820 #ifdef FEAT_CMDHIST 2821 // When history is in bar lines skip the old style history 2822 // lines. 2823 if (virp->vir_version < VIMINFO_VERSION_WITH_HISTORY) 2824 eof = read_viminfo_history(virp, writing); 2825 else 2826 #endif 2827 eof = viminfo_readline(virp); 2828 break; 2829 case '-': 2830 case '\'': 2831 // When file marks are in bar lines skip the old style lines. 2832 if (virp->vir_version < VIMINFO_VERSION_WITH_MARKS) 2833 eof = read_viminfo_filemark(virp, forceit); 2834 else 2835 eof = viminfo_readline(virp); 2836 break; 2837 default: 2838 if (viminfo_error("E575: ", _("Illegal starting char"), 2839 virp->vir_line)) 2840 eof = TRUE; 2841 else 2842 eof = viminfo_readline(virp); 2843 break; 2844 } 2845 } 2846 2847 #ifdef FEAT_CMDHIST 2848 // Finish reading history items. 2849 if (!writing) 2850 finish_viminfo_history(virp); 2851 #endif 2852 2853 // Change file names to buffer numbers for fmarks. 2854 FOR_ALL_BUFFERS(buf) 2855 fmarks_check_names(buf); 2856 2857 return eof; 2858 } 2859 2860 /* 2861 * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo(). 2862 */ 2863 static void 2864 do_viminfo(FILE *fp_in, FILE *fp_out, int flags) 2865 { 2866 int eof = FALSE; 2867 vir_T vir; 2868 int merge = FALSE; 2869 int do_copy_marks = FALSE; 2870 garray_T buflist; 2871 2872 if ((vir.vir_line = alloc(LSIZE)) == NULL) 2873 return; 2874 vir.vir_fd = fp_in; 2875 vir.vir_conv.vc_type = CONV_NONE; 2876 ga_init2(&vir.vir_barlines, (int)sizeof(char_u *), 100); 2877 vir.vir_version = -1; 2878 2879 if (fp_in != NULL) 2880 { 2881 if (flags & VIF_WANT_INFO) 2882 { 2883 if (fp_out != NULL) 2884 { 2885 // Registers and marks are read and kept separate from what 2886 // this Vim is using. They are merged when writing. 2887 prepare_viminfo_registers(); 2888 prepare_viminfo_marks(); 2889 } 2890 2891 eof = read_viminfo_up_to_marks(&vir, 2892 flags & VIF_FORCEIT, fp_out != NULL); 2893 merge = TRUE; 2894 } 2895 else if (flags != 0) 2896 // Skip info, find start of marks 2897 while (!(eof = viminfo_readline(&vir)) 2898 && vir.vir_line[0] != '>') 2899 ; 2900 2901 do_copy_marks = (flags & 2902 (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT)); 2903 } 2904 2905 if (fp_out != NULL) 2906 { 2907 // Write the info: 2908 fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"), 2909 VIM_VERSION_MEDIUM); 2910 fputs(_("# You may edit it if you're careful!\n\n"), fp_out); 2911 write_viminfo_version(fp_out); 2912 fputs(_("# Value of 'encoding' when this file was written\n"), fp_out); 2913 fprintf(fp_out, "*encoding=%s\n\n", p_enc); 2914 write_viminfo_search_pattern(fp_out); 2915 write_viminfo_sub_string(fp_out); 2916 #ifdef FEAT_CMDHIST 2917 write_viminfo_history(fp_out, merge); 2918 #endif 2919 write_viminfo_registers(fp_out); 2920 finish_viminfo_registers(); 2921 #ifdef FEAT_EVAL 2922 write_viminfo_varlist(fp_out); 2923 #endif 2924 write_viminfo_filemarks(fp_out); 2925 finish_viminfo_marks(); 2926 write_viminfo_bufferlist(fp_out); 2927 write_viminfo_barlines(&vir, fp_out); 2928 2929 if (do_copy_marks) 2930 ga_init2(&buflist, sizeof(buf_T *), 50); 2931 write_viminfo_marks(fp_out, do_copy_marks ? &buflist : NULL); 2932 } 2933 2934 if (do_copy_marks) 2935 { 2936 copy_viminfo_marks(&vir, fp_out, &buflist, eof, flags); 2937 if (fp_out != NULL) 2938 ga_clear(&buflist); 2939 } 2940 2941 vim_free(vir.vir_line); 2942 if (vir.vir_conv.vc_type != CONV_NONE) 2943 convert_setup(&vir.vir_conv, NULL, NULL); 2944 ga_clear_strings(&vir.vir_barlines); 2945 } 2946 2947 /* 2948 * read_viminfo() -- Read the viminfo file. Registers etc. which are already 2949 * set are not over-written unless "flags" includes VIF_FORCEIT. -- webb 2950 */ 2951 int 2952 read_viminfo( 2953 char_u *file, // file name or NULL to use default name 2954 int flags) // VIF_WANT_INFO et al. 2955 { 2956 FILE *fp; 2957 char_u *fname; 2958 2959 if (no_viminfo()) 2960 return FAIL; 2961 2962 fname = viminfo_filename(file); // get file name in allocated buffer 2963 if (fname == NULL) 2964 return FAIL; 2965 fp = mch_fopen((char *)fname, READBIN); 2966 2967 if (p_verbose > 0) 2968 { 2969 verbose_enter(); 2970 smsg(_("Reading viminfo file \"%s\"%s%s%s"), 2971 fname, 2972 (flags & VIF_WANT_INFO) ? _(" info") : "", 2973 (flags & VIF_WANT_MARKS) ? _(" marks") : "", 2974 (flags & VIF_GET_OLDFILES) ? _(" oldfiles") : "", 2975 fp == NULL ? _(" FAILED") : ""); 2976 verbose_leave(); 2977 } 2978 2979 vim_free(fname); 2980 if (fp == NULL) 2981 return FAIL; 2982 2983 viminfo_errcnt = 0; 2984 do_viminfo(fp, NULL, flags); 2985 2986 fclose(fp); 2987 return OK; 2988 } 2989 2990 /* 2991 * Write the viminfo file. The old one is read in first so that effectively a 2992 * merge of current info and old info is done. This allows multiple vims to 2993 * run simultaneously, without losing any marks etc. 2994 * If "forceit" is TRUE, then the old file is not read in, and only internal 2995 * info is written to the file. 2996 */ 2997 void 2998 write_viminfo(char_u *file, int forceit) 2999 { 3000 char_u *fname; 3001 FILE *fp_in = NULL; // input viminfo file, if any 3002 FILE *fp_out = NULL; // output viminfo file 3003 char_u *tempname = NULL; // name of temp viminfo file 3004 stat_T st_new; // mch_stat() of potential new file 3005 #if defined(UNIX) || defined(VMS) 3006 mode_t umask_save; 3007 #endif 3008 #ifdef UNIX 3009 int shortname = FALSE; // use 8.3 file name 3010 stat_T st_old; // mch_stat() of existing viminfo file 3011 #endif 3012 #ifdef MSWIN 3013 int hidden = FALSE; 3014 #endif 3015 3016 if (no_viminfo()) 3017 return; 3018 3019 fname = viminfo_filename(file); // may set to default if NULL 3020 if (fname == NULL) 3021 return; 3022 3023 fp_in = mch_fopen((char *)fname, READBIN); 3024 if (fp_in == NULL) 3025 { 3026 int fd; 3027 3028 // if it does exist, but we can't read it, don't try writing 3029 if (mch_stat((char *)fname, &st_new) == 0) 3030 goto end; 3031 3032 // Create the new .viminfo non-accessible for others, because it may 3033 // contain text from non-accessible documents. It is up to the user to 3034 // widen access (e.g. to a group). This may also fail if there is a 3035 // race condition, then just give up. 3036 fd = mch_open((char *)fname, 3037 O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600); 3038 if (fd < 0) 3039 goto end; 3040 fp_out = fdopen(fd, WRITEBIN); 3041 } 3042 else 3043 { 3044 /* 3045 * There is an existing viminfo file. Create a temporary file to 3046 * write the new viminfo into, in the same directory as the 3047 * existing viminfo file, which will be renamed once all writing is 3048 * successful. 3049 */ 3050 #ifdef UNIX 3051 /* 3052 * For Unix we check the owner of the file. It's not very nice to 3053 * overwrite a user's viminfo file after a "su root", with a 3054 * viminfo file that the user can't read. 3055 */ 3056 st_old.st_dev = (dev_t)0; 3057 st_old.st_ino = 0; 3058 st_old.st_mode = 0600; 3059 if (mch_stat((char *)fname, &st_old) == 0 3060 && getuid() != ROOT_UID 3061 && !(st_old.st_uid == getuid() 3062 ? (st_old.st_mode & 0200) 3063 : (st_old.st_gid == getgid() 3064 ? (st_old.st_mode & 0020) 3065 : (st_old.st_mode & 0002)))) 3066 { 3067 int tt = msg_didany; 3068 3069 // avoid a wait_return for this message, it's annoying 3070 semsg(_("E137: Viminfo file is not writable: %s"), fname); 3071 msg_didany = tt; 3072 fclose(fp_in); 3073 goto end; 3074 } 3075 #endif 3076 #ifdef MSWIN 3077 // Get the file attributes of the existing viminfo file. 3078 hidden = mch_ishidden(fname); 3079 #endif 3080 3081 /* 3082 * Make tempname, find one that does not exist yet. 3083 * Beware of a race condition: If someone logs out and all Vim 3084 * instances exit at the same time a temp file might be created between 3085 * stat() and open(). Use mch_open() with O_EXCL to avoid that. 3086 * May try twice: Once normal and once with shortname set, just in 3087 * case somebody puts his viminfo file in an 8.3 filesystem. 3088 */ 3089 for (;;) 3090 { 3091 int next_char = 'z'; 3092 char_u *wp; 3093 3094 tempname = buf_modname( 3095 #ifdef UNIX 3096 shortname, 3097 #else 3098 FALSE, 3099 #endif 3100 fname, 3101 #ifdef VMS 3102 (char_u *)"-tmp", 3103 #else 3104 (char_u *)".tmp", 3105 #endif 3106 FALSE); 3107 if (tempname == NULL) // out of memory 3108 break; 3109 3110 /* 3111 * Try a series of names. Change one character, just before 3112 * the extension. This should also work for an 8.3 3113 * file name, when after adding the extension it still is 3114 * the same file as the original. 3115 */ 3116 wp = tempname + STRLEN(tempname) - 5; 3117 if (wp < gettail(tempname)) // empty file name? 3118 wp = gettail(tempname); 3119 for (;;) 3120 { 3121 /* 3122 * Check if tempfile already exists. Never overwrite an 3123 * existing file! 3124 */ 3125 if (mch_stat((char *)tempname, &st_new) == 0) 3126 { 3127 #ifdef UNIX 3128 /* 3129 * Check if tempfile is same as original file. May happen 3130 * when modname() gave the same file back. E.g. silly 3131 * link, or file name-length reached. Try again with 3132 * shortname set. 3133 */ 3134 if (!shortname && st_new.st_dev == st_old.st_dev 3135 && st_new.st_ino == st_old.st_ino) 3136 { 3137 VIM_CLEAR(tempname); 3138 shortname = TRUE; 3139 break; 3140 } 3141 #endif 3142 } 3143 else 3144 { 3145 // Try creating the file exclusively. This may fail if 3146 // another Vim tries to do it at the same time. 3147 #ifdef VMS 3148 // fdopen() fails for some reason 3149 umask_save = umask(077); 3150 fp_out = mch_fopen((char *)tempname, WRITEBIN); 3151 (void)umask(umask_save); 3152 #else 3153 int fd; 3154 3155 // Use mch_open() to be able to use O_NOFOLLOW and set file 3156 // protection: 3157 // Unix: same as original file, but strip s-bit. Reset 3158 // umask to avoid it getting in the way. 3159 // Others: r&w for user only. 3160 # ifdef UNIX 3161 umask_save = umask(0); 3162 fd = mch_open((char *)tempname, 3163 O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 3164 (int)((st_old.st_mode & 0777) | 0600)); 3165 (void)umask(umask_save); 3166 # else 3167 fd = mch_open((char *)tempname, 3168 O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600); 3169 # endif 3170 if (fd < 0) 3171 { 3172 fp_out = NULL; 3173 # ifdef EEXIST 3174 // Avoid trying lots of names while the problem is lack 3175 // of permission, only retry if the file already 3176 // exists. 3177 if (errno != EEXIST) 3178 break; 3179 # endif 3180 } 3181 else 3182 fp_out = fdopen(fd, WRITEBIN); 3183 #endif // VMS 3184 if (fp_out != NULL) 3185 break; 3186 } 3187 3188 // Assume file exists, try again with another name. 3189 if (next_char == 'a' - 1) 3190 { 3191 // They all exist? Must be something wrong! Don't write 3192 // the viminfo file then. 3193 semsg(_("E929: Too many viminfo temp files, like %s!"), 3194 tempname); 3195 break; 3196 } 3197 *wp = next_char; 3198 --next_char; 3199 } 3200 3201 if (tempname != NULL) 3202 break; 3203 // continue if shortname was set 3204 } 3205 3206 #if defined(UNIX) && defined(HAVE_FCHOWN) 3207 if (tempname != NULL && fp_out != NULL) 3208 { 3209 stat_T tmp_st; 3210 3211 /* 3212 * Make sure the original owner can read/write the tempfile and 3213 * otherwise preserve permissions, making sure the group matches. 3214 */ 3215 if (mch_stat((char *)tempname, &tmp_st) >= 0) 3216 { 3217 if (st_old.st_uid != tmp_st.st_uid) 3218 // Changing the owner might fail, in which case the 3219 // file will now owned by the current user, oh well. 3220 vim_ignored = fchown(fileno(fp_out), st_old.st_uid, -1); 3221 if (st_old.st_gid != tmp_st.st_gid 3222 && fchown(fileno(fp_out), -1, st_old.st_gid) == -1) 3223 // can't set the group to what it should be, remove 3224 // group permissions 3225 (void)mch_setperm(tempname, 0600); 3226 } 3227 else 3228 // can't stat the file, set conservative permissions 3229 (void)mch_setperm(tempname, 0600); 3230 } 3231 #endif 3232 } 3233 3234 /* 3235 * Check if the new viminfo file can be written to. 3236 */ 3237 if (fp_out == NULL) 3238 { 3239 semsg(_("E138: Can't write viminfo file %s!"), 3240 (fp_in == NULL || tempname == NULL) ? fname : tempname); 3241 if (fp_in != NULL) 3242 fclose(fp_in); 3243 goto end; 3244 } 3245 3246 if (p_verbose > 0) 3247 { 3248 verbose_enter(); 3249 smsg(_("Writing viminfo file \"%s\""), fname); 3250 verbose_leave(); 3251 } 3252 3253 viminfo_errcnt = 0; 3254 do_viminfo(fp_in, fp_out, forceit ? 0 : (VIF_WANT_INFO | VIF_WANT_MARKS)); 3255 3256 if (fclose(fp_out) == EOF) 3257 ++viminfo_errcnt; 3258 3259 if (fp_in != NULL) 3260 { 3261 fclose(fp_in); 3262 3263 // In case of an error keep the original viminfo file. Otherwise 3264 // rename the newly written file. Give an error if that fails. 3265 if (viminfo_errcnt == 0) 3266 { 3267 if (vim_rename(tempname, fname) == -1) 3268 { 3269 ++viminfo_errcnt; 3270 semsg(_("E886: Can't rename viminfo file to %s!"), fname); 3271 } 3272 # ifdef MSWIN 3273 // If the viminfo file was hidden then also hide the new file. 3274 else if (hidden) 3275 mch_hide(fname); 3276 # endif 3277 } 3278 if (viminfo_errcnt > 0) 3279 mch_remove(tempname); 3280 } 3281 3282 end: 3283 vim_free(fname); 3284 vim_free(tempname); 3285 } 3286 3287 /* 3288 * ":rviminfo" and ":wviminfo". 3289 */ 3290 void 3291 ex_viminfo( 3292 exarg_T *eap) 3293 { 3294 char_u *save_viminfo; 3295 3296 save_viminfo = p_viminfo; 3297 if (*p_viminfo == NUL) 3298 p_viminfo = (char_u *)"'100"; 3299 if (eap->cmdidx == CMD_rviminfo) 3300 { 3301 if (read_viminfo(eap->arg, VIF_WANT_INFO | VIF_WANT_MARKS 3302 | (eap->forceit ? VIF_FORCEIT : 0)) == FAIL) 3303 emsg(_("E195: Cannot open viminfo file for reading")); 3304 } 3305 else 3306 write_viminfo(eap->arg, eap->forceit); 3307 p_viminfo = save_viminfo; 3308 } 3309 3310 #endif // FEAT_VIMINFO 3311