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