diff src/ex_cmds.c @ 9272:f5d9eb512f8b v7.4.1919

commit https://github.com/vim/vim/commit/46bbb0c4ba27395859dfeaa26938483946bb4ec2 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jun 11 21:04:39 2016 +0200 patch 7.4.1919 Problem: Register contents is not merged when writing viminfo. Solution: Use timestamps for register contents.
author Christian Brabandt <cb@256bit.org>
date Sat, 11 Jun 2016 21:15:05 +0200
parents 79cb08f0d812
children fd81f36cd5b6
line wrap: on
line diff
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -1750,7 +1750,7 @@ append_redir(
 #if defined(FEAT_VIMINFO) || defined(PROTO)
 
 static int no_viminfo(void);
-static int read_viminfo_barline(vir_T *virp, int got_encoding, int writing);
+static int read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing);
 static void write_viminfo_version(FILE *fp_out);
 static void write_viminfo_barlines(vir_T *virp, FILE *fp_out);
 static int  viminfo_errcnt;
@@ -2164,6 +2164,10 @@ do_viminfo(FILE *fp_in, FILE *fp_out, in
     {
 	if (flags & VIF_WANT_INFO)
 	{
+	    /* Registers are read and newer ones are used when writing. */
+	    if (fp_out != NULL)
+		prepare_viminfo_registers();
+
 	    eof = read_viminfo_up_to_marks(&vir,
 					 flags & VIF_FORCEIT, fp_out != NULL);
 	    merge = TRUE;
@@ -2191,6 +2195,7 @@ do_viminfo(FILE *fp_in, FILE *fp_out, in
 	write_viminfo_history(fp_out, merge);
 #endif
 	write_viminfo_registers(fp_out);
+	finish_viminfo_registers();
 #ifdef FEAT_EVAL
 	write_viminfo_varlist(fp_out);
 #endif
@@ -2229,6 +2234,7 @@ read_viminfo_up_to_marks(
 #ifdef FEAT_CMDHIST
     prepare_viminfo_history(forceit ? 9999 : 0, writing);
 #endif
+
     eof = viminfo_readline(virp);
     while (!eof && virp->vir_line[0] != '>')
     {
@@ -2246,7 +2252,8 @@ read_viminfo_up_to_marks(
 		eof = viminfo_readline(virp);
 		break;
 	    case '|':
-		eof = read_viminfo_barline(virp, got_encoding, writing);
+		eof = read_viminfo_barline(virp, got_encoding,
+							    forceit, writing);
 		break;
 	    case '*': /* "*encoding=value" */
 		got_encoding = TRUE;
@@ -2263,7 +2270,15 @@ read_viminfo_up_to_marks(
 		eof = read_viminfo_bufferlist(virp, writing);
 		break;
 	    case '"':
-		eof = read_viminfo_register(virp, forceit);
+		/* When registers are in bar lines skip the old style register
+		 * lines. */
+		if (virp->vir_version < VIMINFO_VERSION_WITH_REGISTERS)
+		    eof = read_viminfo_register(virp, forceit);
+		else
+		    do {
+			eof = viminfo_readline(virp);
+		    } while (!eof && (virp->vir_line[0] == TAB
+						|| virp->vir_line[0] == '<'));
 		break;
 	    case '/':	    /* Search string */
 	    case '&':	    /* Substitute search string */
@@ -2527,20 +2542,20 @@ barline_writestring(FILE *fd, char_u *s,
 	}
     }
     putc('"', fd);
-    return remaining;
+    return remaining - 2;
 }
 
 /*
  * Parse a viminfo line starting with '|'.
- * Put each decoded value in "values" and return the number of values found.
+ * Add each decoded value to "values".
  */
-    static int
-barline_parse(vir_T *virp, char_u *text, bval_T *values)
+    static void
+barline_parse(vir_T *virp, char_u *text, garray_T *values)
 {
     char_u  *p = text;
     char_u  *nextp = NULL;
     char_u  *buf = NULL;
-    int	    count = 0;
+    bval_T  *value;
     int	    i;
     int	    allocated = FALSE;
 #ifdef FEAT_MBYTE
@@ -2550,27 +2565,27 @@ barline_parse(vir_T *virp, char_u *text,
 
     while (*p == ',')
     {
-	if (count == BVAL_MAX)
-	{
-	    EMSG2(e_intern2, "barline_parse()");
+	++p;
+	if (ga_grow(values, 1) == FAIL)
 	    break;
-	}
-	++p;
+	value = (bval_T *)(values->ga_data) + values->ga_len;
 
 	if (*p == '>')
 	{
-	    /* Need to read a continuation line.  Need to put strings in
-	     * allocated memory, because virp->vir_line is overwritten. */
+	    /* Need to read a continuation line.  Put strings in allocated
+	     * memory, because virp->vir_line is overwritten. */
 	    if (!allocated)
 	    {
-		for (i = 0; i < count; ++i)
-		    if (values[i].bv_type == BVAL_STRING
-						   && !values[i].bv_allocated)
+		for (i = 0; i < values->ga_len; ++i)
+		{
+		    bval_T  *vp = (bval_T *)(values->ga_data) + i;
+
+		    if (vp->bv_type == BVAL_STRING && !vp->bv_allocated)
 		    {
-			values[i].bv_string = vim_strnsave(
-				       values[i].bv_string, values[i].bv_len);
-			values[i].bv_allocated = TRUE;
+			vp->bv_string = vim_strnsave(vp->bv_string, vp->bv_len);
+			vp->bv_allocated = TRUE;
 		    }
+		}
 		allocated = TRUE;
 	    }
 
@@ -2590,7 +2605,7 @@ barline_parse(vir_T *virp, char_u *text,
 		len = getdigits(&p);
 		buf = alloc((int)(len + 1));
 		if (buf == NULL)
-		    return count;
+		    return;
 		p = buf;
 		for (todo = len; todo > 0; todo -= n)
 		{
@@ -2599,7 +2614,7 @@ barline_parse(vir_T *virp, char_u *text,
 		    {
 			/* file was truncated or garbled */
 			vim_free(buf);
-			return count;
+			return;
 		    }
 		    /* Get length of text, excluding |< and NL chars. */
 		    n = STRLEN(virp->vir_line);
@@ -2628,16 +2643,16 @@ barline_parse(vir_T *virp, char_u *text,
 		if (viminfo_readline(virp) || virp->vir_line[0] != '|'
 					      || virp->vir_line[1] != '<')
 		    /* file was truncated or garbled */
-		    return count;
+		    return;
 		p = virp->vir_line + 2;
 	    }
 	}
 
 	if (isdigit(*p))
 	{
-	    values[count].bv_type = BVAL_NR;
-	    values[count].bv_nr = getdigits(&p);
-	    ++count;
+	    value->bv_type = BVAL_NR;
+	    value->bv_nr = getdigits(&p);
+	    ++values->ga_len;
 	}
 	else if (*p == '"')
 	{
@@ -2649,7 +2664,7 @@ barline_parse(vir_T *virp, char_u *text,
 	    while (*p != '"')
 	    {
 		if (*p == NL || *p == NUL)
-		    return count;  /* syntax error, drop the value */
+		    return;  /* syntax error, drop the value */
 		if (*p == '\\')
 		{
 		    ++p;
@@ -2662,6 +2677,7 @@ barline_parse(vir_T *virp, char_u *text,
 		else
 		    s[len++] = *p++;
 	    }
+	    ++p;
 	    s[len] = NUL;
 
 #ifdef FEAT_MBYTE
@@ -2683,15 +2699,15 @@ barline_parse(vir_T *virp, char_u *text,
 	     * above and we did allocate before, thus vir_line may change. */
 	    if (s != buf && allocated)
 		s = vim_strsave(s);
-	    values[count].bv_string = s;
-	    values[count].bv_type = BVAL_STRING;
-	    values[count].bv_len = len;
-	    values[count].bv_allocated = allocated
+	    value->bv_string = s;
+	    value->bv_type = BVAL_STRING;
+	    value->bv_len = len;
+	    value->bv_allocated = allocated
 #ifdef FEAT_MBYTE
 					    || converted
 #endif
 						;
-	    ++count;
+	    ++values->ga_len;
 	    if (nextp != NULL)
 	    {
 		/* values following a long string */
@@ -2701,23 +2717,21 @@ barline_parse(vir_T *virp, char_u *text,
 	}
 	else if (*p == ',')
 	{
-	    values[count].bv_type = BVAL_EMPTY;
-	    ++count;
+	    value->bv_type = BVAL_EMPTY;
+	    ++values->ga_len;
 	}
 	else
 	    break;
     }
-
-    return count;
 }
 
     static int
-read_viminfo_barline(vir_T *virp, int got_encoding, int writing)
+read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing)
 {
     char_u	*p = virp->vir_line + 1;
     int		bartype;
-    bval_T	values[BVAL_MAX];
-    int		count = 0;
+    garray_T	values;
+    bval_T	*vp;
     int		i;
 
     /* The format is: |{bartype},{value},...
@@ -2737,6 +2751,7 @@ read_viminfo_barline(vir_T *virp, int go
     }
     else
     {
+	ga_init2(&values, sizeof(bval_T), 20);
 	bartype = getdigits(&p);
 	switch (bartype)
 	{
@@ -2746,15 +2761,21 @@ read_viminfo_barline(vir_T *virp, int go
 		 * doesn't understand the version. */
 		if (!got_encoding)
 		{
-		    count = barline_parse(virp, p, values);
-		    if (count > 0 && values[0].bv_type == BVAL_NR)
-			virp->vir_version = values[0].bv_nr;
+		    barline_parse(virp, p, &values);
+		    vp = (bval_T *)values.ga_data;
+		    if (values.ga_len > 0 && vp->bv_type == BVAL_NR)
+			virp->vir_version = vp->bv_nr;
 		}
 		break;
 
 	    case BARTYPE_HISTORY:
-		count = barline_parse(virp, p, values);
-		handle_viminfo_history(values, count, writing);
+		barline_parse(virp, p, &values);
+		handle_viminfo_history(&values, writing);
+		break;
+
+	    case BARTYPE_REGISTER:
+		barline_parse(virp, p, &values);
+		handle_viminfo_register(&values, force);
 		break;
 
 	    default:
@@ -2762,11 +2783,14 @@ read_viminfo_barline(vir_T *virp, int go
 		if (writing)
 		    ga_add_string(&virp->vir_barlines, virp->vir_line);
 	}
-    }
-
-    for (i = 0; i < count; ++i)
-	if (values[i].bv_type == BVAL_STRING && values[i].bv_allocated)
-	    vim_free(values[i].bv_string);
+	for (i = 0; i < values.ga_len; ++i)
+	{
+	    vp = (bval_T *)values.ga_data + i;
+	    if (vp->bv_type == BVAL_STRING && vp->bv_allocated)
+		vim_free(vp->bv_string);
+	}
+	ga_clear(&values);
+    }
 
     return viminfo_readline(virp);
 }
@@ -2794,6 +2818,22 @@ write_viminfo_barlines(vir_T *virp, FILE
 }
 #endif /* FEAT_VIMINFO */
 
+#if defined(FEAT_VIMINFO) || defined(PROTO)
+/*
+ * Return the current time in seconds.  Calls time(), unless test_settime()
+ * was used.
+ */
+    time_t
+vim_time(void)
+{
+# ifdef FEAT_EVAL
+    return time_for_testing == 0 ? time(NULL) : time_for_testing;
+# else
+    return time(NULL);
+# endif
+}
+#endif
+
 /*
  * Implementation of ":fixdel", also used by get_stty().
  *  <BS>    resulting <Del>