?

Log in

No account? Create an account

Приключения юниксиста (юниксоида?) под виндами - Общество дровосеков Бердичева по изучению Мишны

Jan. 5th, 2015

06:24 pm - Приключения юниксиста (юниксоида?) под виндами

Previous Entry Share Next Entry



Понадобилось мне давеча спортировать одно консольное приложение под винды (Win7). Ну что, приложение как приложение, ничего особенного. Ну пользуется юникодом, ну пользуется ESC-последовательностями, казалось бы, делов-то куча. Ан нет.

Засада номер 1: На середине второго десятилетия XXI века надо руками включать юникод (chcp 65001).

Засада номер 2: Если байты UTF-8, относящиеся к одному символу, разорваны на два системных вызова write, то на экране получаем козью морду, а не символ юникода. Пришлось плюнуть и на chcp 65001, и на системный вызов write, и воспользоваться WriteConsoleW (для этого пришлось написать функцию сбора юникода из байтиков, естественно).

Засада номер 3: Из-за большого ума Майкрософт решил не реализовывать ESC-последовательности в консольном окне. Пользуйтесь, дескать, разработчики дорогие, нашим всемогущим console API и не выпендривайтесь.
— Что? Переносимость? Какая в подоконник переносимость?
Ну ладно, так и быть, нашел я https://github.com/adoxa/ansicon

Итого, убил полдня на то, что должно было просто работать™, причем так мало исключительно благодаря ansicon. И так у них всё

Comments:

[User Picture]
From:yatur
Date:January 6th, 2015 02:55 am (UTC)
(Link)
Ты еще пожалуйся на слэши не в ту сторону :)

Консоль в виндах по большей части для обратной совместимости с ДОСом и досообразными утилитами под Windows 3.1. Поэтому полный Юникод там по умолчанию выключен - ну какой в ДОСе может быть Юникод?

В Юниксе виндузятнику тоже бывает не слишком уютно. Во-первых, там нет диска C:... :D
(Reply) (Thread)
[User Picture]
From:archaicos
Date:January 6th, 2015 02:58 am (UTC)
(Link)
Файлы с UNIX slash'ами открываются нормально ещё со времён дремучего DOS'а.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:archaicos
Date:January 6th, 2015 02:59 am (UTC)
(Link)
Это всё фигня. Но вот выбрать Unicode шрифт программным образом без хаков нельзя в принципе. Нет публичного документированного API. :)
(Reply) (Thread)
[User Picture]
From:spamsink
Date:January 6th, 2015 03:39 am (UTC)
(Link)
Очередное "слушайте свои Валенки".
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:ramlamyammambam
Date:January 6th, 2015 03:09 am (UTC)
(Link)
Может, есть какой-нибудь альтернативный cmd.exe?
(Reply) (Thread)
[User Picture]
From:spamsink
Date:January 6th, 2015 03:41 am (UTC)
(Link)
ANSICON запускает из-под себя cmd.exe, в котором ESC-последовательности начинают магическим образом работать. Можно считать его таким альтернативным cmd.exe.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:fatoff
Date:January 6th, 2015 04:14 am (UTC)
(Link)
Да вроде в Windows 10 они слегка подтянули консоль до. Но не смотрел пока.
Никогда не пользуюсь системными вызовами, что отрабатывать UTF8. Лучше всего это сделано в библиотеке Qt.

А у меня из-за апгрейда ядра Linux с одного минорного индекса вроде Major.Minor -> Major.Minor + 3 отключился WiFi, и единственный способ получить его снова - грузиться в Major.Minor - 3 нынешний. 3.13.0-40 -> 3.13.0-43 -- позор джунглям!

Edited at 2015-01-06 04:38 am (UTC)
(Reply) (Thread)
[User Picture]
From:spamsink
Date:January 6th, 2015 05:07 am (UTC)
(Link)
Пока мне Win10 никто не предлагает. Насчет линукса, похоже, надо найти работающую конфигурацию ядра и не трогать ее, пока совсем не припрет, а не гнаться за bleeding edge of gums of a free horse. А вот что действительно позор джунглям, так это поведение виндовой консоли при разрыве UTF-8. Совершенно непростительная ошибка, sophomoric до мозга костей.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:ak_47
Date:January 6th, 2015 04:25 am (UTC)
(Link)
Справедливо. Консоль в Винде совершенно позорная.
(Reply) (Thread)
[User Picture]
From:sab123
Date:January 6th, 2015 05:19 am (UTC)
(Link)
write() - НЕ системный вызов в виндах.

Правильно выводить 16-битный юникод на стандартный вывод так: у stdout включается режим Юникода через _setmode(), и потом туда можно писать через wprintf() и тому подобное. Еще желательно посылать первый символ 0xFEFF (или наоборот 0xFFFE, не помню), иначе если устраивать конвейер, не все программы прочухают юникодность. Для конверсии из UTF-8 есть готовые функции, вроде MultiByteToWideChar() правиальная.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:January 6th, 2015 07:03 am (UTC)
(Link)
Хорошо, позиксный вызов. Дальнейшее не "правильно", а способ обойти ошибку. Если кодовая страница у устройства вывода - UTF-8 (на виндовом языке 65001), то UTF-8 byte stream, посланный в файловый дескриптор, ассоциированный с этим устройством, путем вызовов write, должен просто работать™, т.е. корректно отображаться при любой группировке байтов по вызовам, хоть по одному зараз.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:ilya_dogolazky
Date:January 6th, 2015 08:30 am (UTC)
(Link)
а сигвинчиком теперь не модно пользоваться?
(Reply) (Thread)
[User Picture]
From:spamsink
Date:January 6th, 2015 09:52 am (UTC)
(Link)
Надо, чтобы самостоятельно работало, без установки дополнительных пакетов.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:vaddimka
Date:January 6th, 2015 03:55 pm (UTC)
(Link)
ой, там проще конвертировать UTF-8 в двубайтовый юникод и писать системными вызовами (на виндовсе) и гнать UTF-8 напрямую (макось и линукс)
у меня так нормально работает и в макоси и в виндовсе (и в линуксе наверное тоже, но не проверял еще)
есть обертка для плюсов, называется Boost.Nowide

Edited at 2015-01-06 03:57 pm (UTC)
(Reply) (Thread)
[User Picture]
From:spamsink
Date:January 6th, 2015 04:39 pm (UTC)
(Link)
"Проще", ну так бардак же.
В данном случае код чисто сишный, так что буст не помогает.
(Reply) (Parent) (Thread) (Expand)
(Deleted comment)
[User Picture]
From:spamsink
Date:January 9th, 2015 07:38 pm (UTC)
(Link)
Чего? Иероглифы в консоли даже в досе работали, иначе как бы японцы досом пользовались. Раз есть консольная команда chcp, всё должно работать как следует.

Буфер обмена с юникодной консолью (той самой, текстовой, на которую переключаться с помощью ctrl-alt-F1) в линуксах работает отлично. Даже если делать паузу между байтами UTF-8, всё равно вылезают русские буквы. В виндах просто ошибка в библиотеке. Какой-то идиот не подумал, что UTF-8 может быть разорван пополам.
(Reply) (Parent) (Thread)