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