AutoCAD2021 и кодировка создаваемых файлов
Наконец-то вышел ACAD2021, и мне стало интересно, что там поменялось (и поменялось ли) по крайней мере в части кодировки создаваемых файлов.
Вот говорила мне мама - прежде чем высказываться, почитай документацию!
В ACAD2021 появилась новая системная переменная LISPSYS (далее вольный перевод официальной документации):
Тип - целый
Хранится в реестре
Возможные значения | Описание |
0 (начальное значение) | VLIDE установлена как редактор кодов lsp по умолчанию, lisp не поддерживает UTF ни в каком виде. Исходные файлы сохраняются в кодировке ANSI и с ее же использованием компилируются. |
1 | VisualStudio устанавливается в качестве редактора lsp по умолчанию. Т.е., если она установлена, именно она и будет вызываться по команде _.vlide. Заявлено, что lisp функции полностью поддерживают Unicode lsp-файлы при сохранении из-под VS используют кодировку UTF и компилируются с ее использованием |
2 | VisualStudio устанавливается в качестве редактора lsp по умолчанию. Т.е., если она установлена, именно она и будет вызываться по команде _.vlide. Заявлено, что lisp функции полностью поддерживают Unicode lsp файлы при сохранении используют Unicode, но при компиляции - ANSI |
После изменения LISPSYS AutoCAD необходимо перезапускать.
Лично мне слабо интересно значение 2: если (не приведи боже) в коде прописано создание диалогов на лету, что мы получим в результате компиляции в fas/vlx, неизвестно никому. А тут "вероятность провала равна провалу", как говаривал папаша Мюллер (с).
Немного оффтопа. По поводу того, как выполнялись тесты и почему.
В ACAD2019 были созданы исходные коды и сохранены как lsp-файл. Сделано намеренно, поскольку ни один из пользователей / разработчиков не станет перелопачивать, переоткрывать и пересохранять тьму исходников. Соответственно lsp сохранены в кодировке ANSI. Файлы (независимо от значения LISPSYS) загружаются в AutoCAD с использованием команды _.appload либо просто "перетаскиванием" исходного кода в графическую область. SECURELOAD временно установлена равной 0.
Тестирование выполняется в английском AutoCAD 2021 x64, обновлений для ACAD на момент публикации не выходило.
Оффтоп кончился, дальше по делу.
Проверим варианты чтения текстовых файлов, записи текстовых же файлов и чтения программно записанных файлов при различных значениях LISPSYS? Ну а почему бы и нет?
Для начала создадим несколько файлов, содержащих один и тот же текст
1 2 | Русский текст English words |
В различных кодировках: ANSI-1251, UTF-8. Соответствено обзовем их как c:\coding\ansi.txt, c:\coding\utf-8.txt.
Используем элементарные лиспы для чтения текстовых файлов из предопределенного каталога (ну, у нас же исследовательские задачи, верно?) и вываливания в alert того, чего начитали:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | (defun c:read-files (/ path handle str lst) (setq path "c:\\coding" lst (mapcar (function (lambda (file / handle str res) (setq handle (open file "r")) (while (setq str (read-line handle)) (setq res (cons str res))) (close handle) (strcat (vl-filename-base file) (vl-filename-extension file) (apply (function strcat) (mapcar (function (lambda (x) (strcat "\n" x))) (reverse res))) ) ;_ end of strcat ) ;_ end of lambda ) ;_ end of function (mapcar (function (lambda (x) (strcat path "\\" x))) (vl-directory-files path "*.txt")) ) ;_ end of mapcar lst (strcat "LISPSYS = " (if (getvar "lispsys") ; Тут просто сработала моя паранойя (itoa (getvar "lispsys")) "NONE" ) ;_ end of if (apply (function strcat) (mapcar (function (lambda (x) (strcat "\n\n" x))) lst)) ) ;_ end of strcat ) ;_ end of setq (alert lst) ; (princ (strcat "\n" lst)) ;; Это если хочется и в ком.строке что-то увидеть (princ) ) ;_ end of defun |
Чтение файлов сведем в табличку:
LISPSYS | Результат | Пояснение |
0 | UTF не прочитан | |
1 | UTF прочитан верно |
А что будет с записью? Повторяю - код создан в более ранней версии, сохранен в кодировке ANSI, загружается в AutoCAD 2021 простым drag-and-drop или через _.appload.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | (defun c:write-files (/ file path handle) (if (setq file (getfiled "File to write" "" "txt" 1)) (progn (setq handle (open file "w")) (foreach item (list (strcat "lispsys = " (if (getvar "lispsys") ; опять моя паранойя... (itoa (getvar "lispsys")) "NONE" ) ;_ end of if ) ;_ end of strcat "Русский текст" "English words" ) ;_ end of list (write-line item handle) ) ;_ end of foreach (close handle) ) ;_ end of progn ) ;_ end of if (princ) ) ;_ end of defun |
И опять же табличка с результатами записи:
Ок, сохраняем файлы как lispsys=0.txt и lispsys=1.txt соответственно, и - та-дааам! - выполняем их чтение. Если создавать те же самые диалоги "на лету" (что я лично ооочень люблю делать), вопрос не покажется уже таким праздным.
LISPSYS | Результат | Пояснение |
0 | Очень интересно! Файл, сохраненный как ANSI - таковым не читается? | |
1 | Тут вообще все прочитано нормально |
Возможно, я что-то упустил и неправильно интерпретировал, но результаты (по крайней мере по чтению программно записанных файлов) выглядят несколько странно.
Также стоит обратить внимание на BOM - Byte Order Mark, в конце UTF файла.
Некоторые редакторы его вставляют/удаляют, некоторые программы не понимают/требуют.
Может приводить к проблемам на ровном месте.
https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%80%D0%BA%D0%B5%D1%80_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%B1%D0%B0%D0%B9%D1%82%D0%BE%D0%B2
Посмотрите в HEX-редакторе (хотя бы во встроенном вьювере Far Manager) ваши текстовые файлы. На кириллическом тексте точно будут видны отличия в 16-ричном представлении UTF-8 от ANSI.
Проблема не в том, чтобы отличить человеку одну кодировку от другой. Проблема в том, как ACAD будет их читать и обрабатывать. Как при работе с некомпилированным lsp-кодом, так и при работе с fas / vlx.