xlocale не работает на OS X? - PullRequest
       5

xlocale не работает на OS X?

5 голосов
/ 26 февраля 2012

У меня есть простая программа, которая тестирует преобразование между wchar_t и char, используя серию локалей, переданных ему в командной строке.Он выводит список неудачных преобразований, распечатывая имя локали и строку, которая не удалось преобразовать.

Я строю его с использованием clang и libc ++.Насколько я понимаю, поддержка именованного языкового стандарта в libc ++ обеспечивается библиотекой xlocale в OS X.

Я вижу некоторые неожиданные сбои, а также некоторые случаи, когда преобразование должно завершиться неудачей, но это не так.

Вот программа.

#warning call this program like: "locale -a | ./a.out" or pass \
locale names valid for your platform, one per line via standard input

#include <iostream>
#include <codecvt>
#include <locale>
#include <array>

template <class Facet>
class usable_facet : public Facet {
public:
    // FIXME: use inheriting constructors when available
    // using Facet::Facet;
    template <class ...Args>
    usable_facet(Args&& ...args) : Facet(std::forward<Args>(args)...) {}
    ~usable_facet() {}
};

int main() {
    std::array<std::wstring,11> args = {L"a",L"é",L"¤",L"€",L"Да",L"Ψ",L"א",L"আ",L"✈",L"가",L"?"};

    std::wstring_convert<usable_facet<std::codecvt_utf8<wchar_t>>> u8cvt; // wchar_t uses UCS-4/UTF-32 on this platform

    int convert_failures = 0;
    std::string line;
    while(std::getline(std::cin,line)) {
        if(line.empty())
            continue;

        using codecvt = usable_facet<std::codecvt_byname<wchar_t,char,std::mbstate_t>>;
        std::wstring_convert<codecvt> convert(new codecvt(line));

        for(auto const &s : args) {
            try {
                convert.to_bytes(s);
            } catch (std::range_error &e) {
                convert_failures++;
                std::cout << line << " : " << u8cvt.to_bytes(s) << '\n';
            }
        }
    }

    std::cout << std::string(80,'=') << '\n';
    std::cout << convert_failures << " wstring_convert to_bytes failures.\n";
}

Вот несколько примеров правильного вывода

en_US.ISO8859-1 : €
en_US.US-ASCII : ✈

Вот пример вывода, который не ожидается

en_US.ISO8859-15 : €

Символ евро существует в кодировке ISO 8859-15, и поэтому он не должен давать сбой.

Вот примеры выходных данных, которые я ожидаю, но не получаю

en_US.ISO8859-15 : ¤
en_US.US-ASCII : ¤

Этосимвол валюты, который существует в ISO 8859-1, но был удален и заменен символом евро в ISO 8859-15.Это преобразование не должно быть успешным, но об ошибке не сообщается.Рассматривая этот случай далее, я обнаружил, что в обоих случаях «¤» преобразуется в 0xA4, что является представлением «88» в ISO 8859-1.

Я не использую xlocale напрямую, только косвенно черезLibc ++.Xlocale в Mac OS X просто сломан с неправильными определениями локали?Есть ли способ это исправить?Или проблемы, которые я вижу, являются результатом чего-то другого?

Ответы [ 2 ]

3 голосов
/ 26 февраля 2012

Я подозреваю, что вы видите проблемы с системой xlocale. сообщение об ошибке будет наиболее ценно!

0 голосов
/ 20 февраля 2013

Я не знаю, почему вы ожидаете, что wchar_t будет UTF-32 или где вы услышали, что «соглашение OS X о том, что wchar_t это UTF-32».Это, конечно, неправильно.Ширина wchar_t составляет всего 16 бит.

См. http://en.wikipedia.org/wiki/Wide_character для получения дополнительной информации о wchar_t.

...