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