var_redir_start(char_u *name, int append)
{
    int		called_emsg_before;
    typval_T	tv;

    // Catch a bad name early.
    if (!eval_isnamec1(*name))
    {
	emsg(_(e_invalid_argument));
	return FAIL;
    }

    // Make a copy of the name, it is used in redir_lval until redir ends.
    redir_varname = vim_strsave(name);
    if (redir_varname == NULL)
	return FAIL;

    if (alloc_redir_lval() == FAIL)
    {
	var_redir_stop();
	return FAIL;
    }

    // The output is stored in growarray "redir_ga" until redirection ends.
    init_redir_ga();

    // Parse the variable name (can be a dict or list entry).
    redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
							     FNE_CHECK_START);
    if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
    {
	clear_lval(redir_lval);
	if (redir_endp != NULL && *redir_endp != NUL)
	    // Trailing characters are present after the variable name
	    semsg(_(e_trailing_characters_str), redir_endp);
	else
	    semsg(_(e_invalid_argument_str), name);
	redir_endp = NULL;  // don't store a value, only cleanup
	var_redir_stop();
	return FAIL;
    }

    // check if we can write to the variable: set it to or append an empty
    // string
    called_emsg_before = called_emsg;
    tv.v_type = VAR_STRING;
    tv.vval.v_string = (char_u *)"";
    if (append)
	set_var_lval(redir_lval, redir_endp, &tv, TRUE,
					     ASSIGN_NO_DECL, (char_u *)".", 0);
    else
	set_var_lval(redir_lval, redir_endp, &tv, TRUE,
					     ASSIGN_NO_DECL, (char_u *)"=", 0);
    clear_lval(redir_lval);
    if (called_emsg > called_emsg_before)
    {
	redir_endp = NULL;  // don't store a value, only cleanup
	var_redir_stop();
	return FAIL;
    }

    return OK;
}
var_redir_start(char_u *name, int append)
{
    int		called_emsg_before;
    typval_T	tv;

     
    if (!eval_isnamec1(*name))
    {
	emsg(_(e_invalid_argument));
	return FAIL;
    }

     
    redir_varname = vim_strsave(name);
    if (redir_varname == NULL)
	return FAIL;

    if (alloc_redir_lval() == FAIL)
    {
	var_redir_stop();
	return FAIL;
    }

     
    init_redir_ga();

     
    redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
							     FNE_CHECK_START);
    if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
    {
	clear_lval(redir_lval);
	if (redir_endp != NULL && *redir_endp != NUL)
	     
	    semsg(_(e_trailing_characters_str), redir_endp);
	else
	    semsg(_(e_invalid_argument_str), name);
	redir_endp = NULL;   
	var_redir_stop();
	return FAIL;
    }

     
     
    called_emsg_before = called_emsg;
    tv.v_type = VAR_STRING;
    tv.vval.v_string = (char_u *)"";
    if (append)
	set_var_lval(redir_lval, redir_endp, &tv, TRUE,
					     ASSIGN_NO_DECL, (char_u *)".", 0);
    else
	set_var_lval(redir_lval, redir_endp, &tv, TRUE,
					     ASSIGN_NO_DECL, (char_u *)"=", 0);
    clear_lval(redir_lval);
    if (called_emsg > called_emsg_before)
    {
	redir_endp = NULL;   
	var_redir_stop();
	return FAIL;
    }

    return OK;
}