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