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