compile_all_expr_in_str(char_u *str, int evalstr, cctx_T *cctx)
{
    char_u	*p = str;
    char_u	*val;
    int		count = 0;

    if (cctx->ctx_skip == SKIP_YES)
	return OK;

    if (!evalstr || *str == NUL)
    {
	// Literal string, possibly empty.
	val = *str != NUL ? vim_strsave(str) : NULL;
	return generate_PUSHS(cctx, &val);
    }

    // Push all the string pieces to the stack, followed by a ISN_CONCAT.
    while (*p != NUL)
    {
	char_u	*lit_start;
	int	escaped_brace = FALSE;

	// Look for a block start.
	lit_start = p;
	while (*p != '{' && *p != '}' && *p != NUL)
	    ++p;

	if (*p != NUL && *p == p[1])
	{
	    // Escaped brace, unescape and continue.
	    // Include the brace in the literal string.
	    ++p;
	    escaped_brace = TRUE;
	}
	else if (*p == '}')
	{
	    semsg(_(e_stray_closing_curly_str), str);
	    return FAIL;
	}

	// Append the literal part.
	if (p != lit_start)
	{
	    val = vim_strnsave(lit_start, (size_t)(p - lit_start));
	    if (generate_PUSHS(cctx, &val) == FAIL)
		return FAIL;
	    ++count;
	}

	if (*p == NUL)
	    break;

	if (escaped_brace)
	{
	    // Skip the second brace.
	    ++p;
	    continue;
	}

	p = compile_one_expr_in_str(p, cctx);
	if (p == NULL)
	    return FAIL;
	++count;
    }

    // Small optimization, if there's only a single piece skip the ISN_CONCAT.
    if (count > 1)
	return generate_CONCAT(cctx, count);

    return OK;
}
compile_all_expr_in_str(char_u *str, int evalstr, cctx_T *cctx)
{
    char_u	*p = str;
    char_u	*val;
    int		count = 0;

    if (cctx->ctx_skip == SKIP_YES)
	return OK;

    if (!evalstr || *str == NUL)
    {
	 
	val = *str != NUL ? vim_strsave(str) : NULL;
	return generate_PUSHS(cctx, &val);
    }

     
    while (*p != NUL)
    {
	char_u	*lit_start;
	int	escaped_brace = FALSE;

	 
	lit_start = p;
	while (*p != '{' && *p != '}' && *p != NUL)
	    ++p;

	if (*p != NUL && *p == p[1])
	{
	     
	     
	    ++p;
	    escaped_brace = TRUE;
	}
	else if (*p == '}')
	{
	    semsg(_(e_stray_closing_curly_str), str);
	    return FAIL;
	}

	 
	if (p != lit_start)
	{
	    val = vim_strnsave(lit_start, (size_t)(p - lit_start));
	    if (generate_PUSHS(cctx, &val) == FAIL)
		return FAIL;
	    ++count;
	}

	if (*p == NUL)
	    break;

	if (escaped_brace)
	{
	     
	    ++p;
	    continue;
	}

	p = compile_one_expr_in_str(p, cctx);
	if (p == NULL)
	    return FAIL;
	++count;
    }

     
    if (count > 1)
	return generate_CONCAT(cctx, count);

    return OK;
}