iconv_open() возвращает EINVAL в Solaris 8

В Solaris 8 это выглядит так iconv*() семейство функций нарушено и поддерживает только преобразование между однобайтовыми кодировками и UTF-8, что можно проверить с помощью этого примера кода:

#include <stdio.h>
#include <errno.h>
#include <iconv.h>

#if defined(__sun) && defined(__SVR4)
#define CP1251 "ansi-1251"
#define ISO_8859_5 "ISO8859-5"
#else
#define CP1251 "CP1251"
#define ISO_8859_5 "ISO-8859-5"
#endif

void iconv_open_debug(const char *, const char *);

int main() {
    iconv_open_debug(CP1251, CP1251);
    iconv_open_debug(CP1251, ISO_8859_5);
    iconv_open_debug(CP1251, "KOI8-R");
    iconv_open_debug(CP1251, "UTF-8");
    iconv_open_debug(CP1251, "WCHAR_T");

    iconv_open_debug(ISO_8859_5, CP1251);
    iconv_open_debug(ISO_8859_5, ISO_8859_5);
    iconv_open_debug(ISO_8859_5, "KOI8-R");
    iconv_open_debug(ISO_8859_5, "UTF-8");
    iconv_open_debug(ISO_8859_5, "WCHAR_T");

    iconv_open_debug("KOI8-R", CP1251);
    iconv_open_debug("KOI8-R", ISO_8859_5);
    iconv_open_debug("KOI8-R", "KOI8-R");
    iconv_open_debug("KOI8-R", "UTF-8");
    iconv_open_debug("KOI8-R", "WCHAR_T");

    iconv_open_debug("UTF-8", CP1251);
    iconv_open_debug("UTF-8", ISO_8859_5);
    iconv_open_debug("UTF-8", "KOI8-R");
    iconv_open_debug("UTF-8", "UTF-8");
    iconv_open_debug("UTF-8", "WCHAR_T");

    iconv_open_debug("WCHAR_T", CP1251);
    iconv_open_debug("WCHAR_T", ISO_8859_5);
    iconv_open_debug("WCHAR_T", "KOI8-R");
    iconv_open_debug("WCHAR_T", "UTF-8");
    iconv_open_debug("WCHAR_T", "WCHAR_T");

    return 0;
}

void iconv_open_debug(const char *from, const char *to) {
    errno = 0;
    if (iconv_open(to, from) == (iconv_t) -1) {
        fprintf(stderr, "iconv_open(\"%s\", \"%s\") FAIL: errno = %d\n", to, from, errno);
        perror("iconv_open()");
    } else {
        fprintf(stdout, "iconv_open(\"%s\", \"%s\") PASS\n", to, from);
    }
}

который только печатает

iconv_open("UTF-8", "ansi-1251") PASS
iconv_open("UTF-8", "ISO8859-5") PASS
iconv_open("UTF-8", "KOI8-R") PASS
iconv_open("ansi-1251", "UTF-8") PASS
iconv_open("ISO8859-5", "UTF-8") PASS
iconv_open("KOI8-R", "UTF-8") PASS

в стандартный вывод и возвращается EINVAL для других пар. Обратите внимание, что даже преобразование в одну и ту же кодировку (например, UTF-8 -> UTF-8) не поддерживается.

Вопросы

  1. Может кто-нибудь ссылаться на документ, описывающий ограничения версии Solaris iconv.h?
  2. Как я могу конвертировать wchar_t* в однобайтовую или многобайтовую строку без поддержки GNU libiconv? wcstombs() было бы хорошо, за исключением того, что он опирается на набор символов текущей локали, в то время как я хочу, чтобы широкая строка была преобразована в обычную строку с использованием определенного набора символов, возможно, отличного от стандартного набора символов.

1 ответ

Решение

Бег sdtconvtool показывает, что большинство устаревших кодовых страниц поддерживаются.

После повторного запуска той же утилиты с truss -u libc::iconv_open Я узнал, что преобразование из одной однобайтовой кодировки в другую однобайтовую кодировку выполняется в два этапа с промежуточным преобразованием в UTF-8,

Говоря о преобразовании из "WCHAR_T", iconv(3) также поддерживает это, но "UCS-4" должен использоваться как имя кодировки источника, так как sizeof(wchar_t) 4 для Solaris (для x86 и SPARC).

Другие вопросы по тегам