convert_setup_ext(
    vimconv_T	*vcp,
    char_u	*from,
    int		from_unicode_is_utf8,
    char_u	*to,
    int		to_unicode_is_utf8)
{
    int		from_prop;
    int		to_prop;
    int		from_is_utf8;
    int		to_is_utf8;

    // Reset to no conversion.
#ifdef USE_ICONV
    if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1)
	iconv_close(vcp->vc_fd);
#endif
    vcp->vc_type = CONV_NONE;
    vcp->vc_factor = 1;
    vcp->vc_fail = FALSE;

    // No conversion when one of the names is empty or they are equal.
    if (from == NULL || *from == NUL || to == NULL || *to == NUL
						     || STRCMP(from, to) == 0)
	return OK;

    from_prop = enc_canon_props(from);
    to_prop = enc_canon_props(to);
    if (from_unicode_is_utf8)
	from_is_utf8 = from_prop & ENC_UNICODE;
    else
	from_is_utf8 = from_prop == ENC_UNICODE;
    if (to_unicode_is_utf8)
	to_is_utf8 = to_prop & ENC_UNICODE;
    else
	to_is_utf8 = to_prop == ENC_UNICODE;

    if ((from_prop & ENC_LATIN1) && to_is_utf8)
    {
	// Internal latin1 -> utf-8 conversion.
	vcp->vc_type = CONV_TO_UTF8;
	vcp->vc_factor = 2;	// up to twice as long
    }
    else if ((from_prop & ENC_LATIN9) && to_is_utf8)
    {
	// Internal latin9 -> utf-8 conversion.
	vcp->vc_type = CONV_9_TO_UTF8;
	vcp->vc_factor = 3;	// up to three as long (euro sign)
    }
    else if (from_is_utf8 && (to_prop & ENC_LATIN1))
    {
	// Internal utf-8 -> latin1 conversion.
	vcp->vc_type = CONV_TO_LATIN1;
    }
    else if (from_is_utf8 && (to_prop & ENC_LATIN9))
    {
	// Internal utf-8 -> latin9 conversion.
	vcp->vc_type = CONV_TO_LATIN9;
    }
#ifdef MSWIN
    // Win32-specific codepage <-> codepage conversion without iconv.
    else if ((from_is_utf8 || encname2codepage(from) > 0)
	    && (to_is_utf8 || encname2codepage(to) > 0))
    {
	vcp->vc_type = CONV_CODEPAGE;
	vcp->vc_factor = 2;	// up to twice as long
	vcp->vc_cpfrom = from_is_utf8 ? 0 : encname2codepage(from);
	vcp->vc_cpto = to_is_utf8 ? 0 : encname2codepage(to);
    }
#endif
#ifdef MACOS_CONVERT
    else if ((from_prop & ENC_MACROMAN) && (to_prop & ENC_LATIN1))
    {
	vcp->vc_type = CONV_MAC_LATIN1;
    }
    else if ((from_prop & ENC_MACROMAN) && to_is_utf8)
    {
	vcp->vc_type = CONV_MAC_UTF8;
	vcp->vc_factor = 2;	// up to twice as long
    }
    else if ((from_prop & ENC_LATIN1) && (to_prop & ENC_MACROMAN))
    {
	vcp->vc_type = CONV_LATIN1_MAC;
    }
    else if (from_is_utf8 && (to_prop & ENC_MACROMAN))
    {
	vcp->vc_type = CONV_UTF8_MAC;
    }
#endif
#ifdef USE_ICONV
    else
    {
	// Use iconv() for conversion.
	vcp->vc_fd = (iconv_t)my_iconv_open(
		to_is_utf8 ? (char_u *)"utf-8" : to,
		from_is_utf8 ? (char_u *)"utf-8" : from);
	if (vcp->vc_fd != (iconv_t)-1)
	{
	    vcp->vc_type = CONV_ICONV;
	    vcp->vc_factor = 4;	// could be longer too...
	}
    }
#endif
    if (vcp->vc_type == CONV_NONE)
	return FAIL;

    return OK;
}
convert_setup_ext(
    vimconv_T	*vcp,
    char_u	*from,
    int		from_unicode_is_utf8,
    char_u	*to,
    int		to_unicode_is_utf8)
{
    int		from_prop;
    int		to_prop;
    int		from_is_utf8;
    int		to_is_utf8;

     
#ifdef USE_ICONV
    if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1)
	iconv_close(vcp->vc_fd);
#endif
    vcp->vc_type = CONV_NONE;
    vcp->vc_factor = 1;
    vcp->vc_fail = FALSE;

     
    if (from == NULL || *from == NUL || to == NULL || *to == NUL
						     || STRCMP(from, to) == 0)
	return OK;

    from_prop = enc_canon_props(from);
    to_prop = enc_canon_props(to);
    if (from_unicode_is_utf8)
	from_is_utf8 = from_prop & ENC_UNICODE;
    else
	from_is_utf8 = from_prop == ENC_UNICODE;
    if (to_unicode_is_utf8)
	to_is_utf8 = to_prop & ENC_UNICODE;
    else
	to_is_utf8 = to_prop == ENC_UNICODE;

    if ((from_prop & ENC_LATIN1) && to_is_utf8)
    {
	 
	vcp->vc_type = CONV_TO_UTF8;
	vcp->vc_factor = 2;	 
    }
    else if ((from_prop & ENC_LATIN9) && to_is_utf8)
    {
	 
	vcp->vc_type = CONV_9_TO_UTF8;
	vcp->vc_factor = 3;	 
    }
    else if (from_is_utf8 && (to_prop & ENC_LATIN1))
    {
	 
	vcp->vc_type = CONV_TO_LATIN1;
    }
    else if (from_is_utf8 && (to_prop & ENC_LATIN9))
    {
	 
	vcp->vc_type = CONV_TO_LATIN9;
    }
#ifdef MSWIN
     
    else if ((from_is_utf8 || encname2codepage(from) > 0)
	    && (to_is_utf8 || encname2codepage(to) > 0))
    {
	vcp->vc_type = CONV_CODEPAGE;
	vcp->vc_factor = 2;	 
	vcp->vc_cpfrom = from_is_utf8 ? 0 : encname2codepage(from);
	vcp->vc_cpto = to_is_utf8 ? 0 : encname2codepage(to);
    }
#endif
#ifdef MACOS_CONVERT
    else if ((from_prop & ENC_MACROMAN) && (to_prop & ENC_LATIN1))
    {
	vcp->vc_type = CONV_MAC_LATIN1;
    }
    else if ((from_prop & ENC_MACROMAN) && to_is_utf8)
    {
	vcp->vc_type = CONV_MAC_UTF8;
	vcp->vc_factor = 2;	 
    }
    else if ((from_prop & ENC_LATIN1) && (to_prop & ENC_MACROMAN))
    {
	vcp->vc_type = CONV_LATIN1_MAC;
    }
    else if (from_is_utf8 && (to_prop & ENC_MACROMAN))
    {
	vcp->vc_type = CONV_UTF8_MAC;
    }
#endif
#ifdef USE_ICONV
    else
    {
	 
	vcp->vc_fd = (iconv_t)my_iconv_open(
		to_is_utf8 ? (char_u *)"utf-8" : to,
		from_is_utf8 ? (char_u *)"utf-8" : from);
	if (vcp->vc_fd != (iconv_t)-1)
	{
	    vcp->vc_type = CONV_ICONV;
	    vcp->vc_factor = 4;	 
	}
    }
#endif
    if (vcp->vc_type == CONV_NONE)
	return FAIL;

    return OK;
}