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