read_viminfo_register(vir_T *virp, int force)
{
    int		eof;
    int		do_it = TRUE;
    int		size;
    int		limit;
    int		i;
    int		set_prev = FALSE;
    char_u	*str;
    char_u	**array = NULL;
    int		new_type = MCHAR; // init to shut up compiler
    colnr_T	new_width = 0; // init to shut up compiler
    yankreg_T	*y_current_p;

    // We only get here (hopefully) if line[0] == '"'
    str = virp->vir_line + 1;

    // If the line starts with "" this is the y_previous register.
    if (*str == '"')
    {
	set_prev = TRUE;
	str++;
    }

    if (!ASCII_ISALNUM(*str) && *str != '-')
    {
	if (viminfo_error("E577: ", _(e_illegal_register_name), virp->vir_line))
	    return TRUE;	// too many errors, pretend end-of-file
	do_it = FALSE;
    }
    get_yank_register(*str++, FALSE);
    y_current_p = get_y_current();
    if (!force && y_current_p->y_array != NULL)
	do_it = FALSE;

    if (*str == '@')
    {
	// "x@: register x used for @@
	if (force || get_execreg_lastc() == NUL)
	    set_execreg_lastc(str[-1]);
    }

    size = 0;
    limit = 100;	// Optimized for registers containing <= 100 lines
    if (do_it)
    {
	// Build the new register in array[].
	// y_array is kept as-is until done.
	// The "do_it" flag is reset when something is wrong, in which case
	// array[] needs to be freed.
	if (set_prev)
	    set_y_previous(y_current_p);
	array = ALLOC_MULT(char_u *, limit);
	str = skipwhite(skiptowhite(str));
	if (STRNCMP(str, "CHAR", 4) == 0)
	    new_type = MCHAR;
	else if (STRNCMP(str, "BLOCK", 5) == 0)
	    new_type = MBLOCK;
	else
	    new_type = MLINE;
	// get the block width; if it's missing we get a zero, which is OK
	str = skipwhite(skiptowhite(str));
	new_width = getdigits(&str);
    }

    while (!(eof = viminfo_readline(virp))
		    && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<'))
    {
	if (do_it)
	{
	    if (size == limit)
	    {
		char_u **new_array = (char_u **)
					   alloc(limit * 2 * sizeof(char_u *));

		if (new_array == NULL)
		{
		    do_it = FALSE;
		    break;
		}
		for (i = 0; i < limit; i++)
		    new_array[i] = array[i];
		vim_free(array);
		array = new_array;
		limit *= 2;
	    }
	    str = viminfo_readstring(virp, 1, TRUE);
	    if (str != NULL)
		array[size++] = str;
	    else
		// error, don't store the result
		do_it = FALSE;
	}
    }

    if (do_it)
    {
	// free y_array[]
	for (i = 0; i < y_current_p->y_size; i++)
	    vim_free(y_current_p->y_array[i]);
	vim_free(y_current_p->y_array);

	y_current_p->y_type = new_type;
	y_current_p->y_width = new_width;
	y_current_p->y_size = size;
	y_current_p->y_time_set = 0;
	if (size == 0)
	{
	    y_current_p->y_array = NULL;
	}
	else
	{
	    // Move the lines from array[] to y_array[].
	    y_current_p->y_array = ALLOC_MULT(char_u *, size);
	    for (i = 0; i < size; i++)
	    {
		if (y_current_p->y_array == NULL)
		    vim_free(array[i]);
		else
		    y_current_p->y_array[i] = array[i];
	    }
	}
    }
    else
    {
	// Free array[] if it was filled.
	for (i = 0; i < size; i++)
	    vim_free(array[i]);
    }
    vim_free(array);

    return eof;
}
read_viminfo_register(vir_T *virp, int force)
{
    int		eof;
    int		do_it = TRUE;
    int		size;
    int		limit;
    int		i;
    int		set_prev = FALSE;
    char_u	*str;
    char_u	**array = NULL;
    int		new_type = MCHAR;  
    colnr_T	new_width = 0;  
    yankreg_T	*y_current_p;

     
    str = virp->vir_line + 1;

     
    if (*str == '"')
    {
	set_prev = TRUE;
	str++;
    }

    if (!ASCII_ISALNUM(*str) && *str != '-')
    {
	if (viminfo_error("E577: ", _(e_illegal_register_name), virp->vir_line))
	    return TRUE;	 
	do_it = FALSE;
    }
    get_yank_register(*str++, FALSE);
    y_current_p = get_y_current();
    if (!force && y_current_p->y_array != NULL)
	do_it = FALSE;

    if (*str == '@')
    {
	 
	if (force || get_execreg_lastc() == NUL)
	    set_execreg_lastc(str[-1]);
    }

    size = 0;
    limit = 100;	 
    if (do_it)
    {
	 
	 
	 
	 
	if (set_prev)
	    set_y_previous(y_current_p);
	array = ALLOC_MULT(char_u *, limit);
	str = skipwhite(skiptowhite(str));
	if (STRNCMP(str, "CHAR", 4) == 0)
	    new_type = MCHAR;
	else if (STRNCMP(str, "BLOCK", 5) == 0)
	    new_type = MBLOCK;
	else
	    new_type = MLINE;
	 
	str = skipwhite(skiptowhite(str));
	new_width = getdigits(&str);
    }

    while (!(eof = viminfo_readline(virp))
		    && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<'))
    {
	if (do_it)
	{
	    if (size == limit)
	    {
		char_u **new_array = (char_u **)
					   alloc(limit * 2 * sizeof(char_u *));

		if (new_array == NULL)
		{
		    do_it = FALSE;
		    break;
		}
		for (i = 0; i < limit; i++)
		    new_array[i] = array[i];
		vim_free(array);
		array = new_array;
		limit *= 2;
	    }
	    str = viminfo_readstring(virp, 1, TRUE);
	    if (str != NULL)
		array[size++] = str;
	    else
		 
		do_it = FALSE;
	}
    }

    if (do_it)
    {
	 
	for (i = 0; i < y_current_p->y_size; i++)
	    vim_free(y_current_p->y_array[i]);
	vim_free(y_current_p->y_array);

	y_current_p->y_type = new_type;
	y_current_p->y_width = new_width;
	y_current_p->y_size = size;
	y_current_p->y_time_set = 0;
	if (size == 0)
	{
	    y_current_p->y_array = NULL;
	}
	else
	{
	     
	    y_current_p->y_array = ALLOC_MULT(char_u *, size);
	    for (i = 0; i < size; i++)
	    {
		if (y_current_p->y_array == NULL)
		    vim_free(array[i]);
		else
		    y_current_p->y_array[i] = array[i];
	    }
	}
    }
    else
    {
	 
	for (i = 0; i < size; i++)
	    vim_free(array[i]);
    }
    vim_free(array);

    return eof;
}