Обсуждение программ nnCron и nnCron LITE
by ebugusey » Sun, 14 Feb 2016, 16:34
Текущая форт система, используемая в nnCron не поддерживает юникод на базовом уровне. Если Вы вдруг захотите какой-то более сложной работы с регулярками, чем латиница и русские символы, то Вы знатно так пролетаете. К томуже S>UNICODE оставляет после себя длину строки в code points (т.е. реальная длина строки в символах), а UNICODE>UTF8 в байтах. И, насколько я помню, CLIPBOARD! не поддерживал нормальное помещение русских символов в буфер, потому что он не указывает кодировку, в которой он эти символы помещает. Попробуйте как-нибудь выполнить - Code: Select all
S" тест" CLIPBOARD!
, а потом вставить это в какую-нибудь unicode-aware программу.
-
ebugusey
-
- Posts: 8
- Joined: Wed, 20 Jan 2016, 20:03
by spronkin » Sun, 14 Feb 2016, 19:21
ebugusey wrote: Если Вы вдруг захотите какой-то более сложной работы с регулярками, чем латиница и русские символы, то Вы знатно так пролетаете. К томуже S>UNICODE оставляет после себя длину строки в code points (т.е. реальная длина строки в символах), а UNICODE>UTF8 в байтах. И, насколько я помню, CLIPBOARD! не поддерживал нормальное помещение русских символов в буфер, потому что он не указывает кодировку, в которой он эти символы помещает. Попробуйте как-нибудь выполнить - Code: Select all
S" тест" CLIPBOARD!
, а потом вставить это в какую-нибудь unicode-aware программу.
Да, я пока слабо представляю, как воспользоваться базовыми возможностями регулярных выражений в nncron, которые позволили хотя бы реализовать функциональность программ sed и grep, т.е. поиск/замену и фильтрацию строковых аргументов в nncron. Пока для этих целей приходится использовать естественно unixutils, но минус этого подхода в том, что для вызова этих программ требуется чтение с жесткого диска. Если бы в nncron были слова SED и GREP, я думаю обработка текста шла бы быстрее. А про поддержку Unicode вообще молчу. Это пока тяжело для меня. Нужно было изначально ее реализовать в приложении с первых бета-версий, а теперь наверное, чтобы это сделать, придется переписывать весь код программы и перекомпилировать.
-

spronkin
-
- Posts: 86
- Joined: Sun, 15 Jan 2012, 13:56
-
by VoidVolker » Sun, 14 Feb 2016, 21:24
spronkin wrote:Да, я пока слабо представляю, как воспользоваться базовыми возможностями регулярных выражений в nncron, которые позволили хотя бы реализовать функциональность программ sed и grep, т.е. поиск/замену и фильтрацию строковых аргументов в nncron.
- Code: Select all
S" D:\path\to\file.ext" S" /(.*\\)(.*)(\..*)/" RE-MATCH DROP $1 S" new_file_name" S+ $3 S+ TYPE CR D:\path\to\new_file_name.ext Ok
spronkin wrote: А про поддержку Unicode вообще молчу. Это пока тяжело для меня. Нужно было изначально ее реализовать в приложении с первых бета-версий, а теперь наверное, чтобы это сделать, придется переписывать весь код программы и перекомпилировать.
Вообще-то, ннкрон создан на основе SP-Forth 3.75. А история SP-Forth насчитывает уже 24 года. Первая версия работала еще под мс-дос (1992). С появлением первых Windows SP-Forth был перенесен на новую платформу, а затем был переписан еще раз для работы в 32-битных системах. И в те далекие времени юникод не был так распространен, как сегодня. Принципиально юникод ничем не отличается от других кодировок и переписывать ннкрон для его поддержки не нужно. Да, я не спорю, в некоторых местах в ннкроне юникод использовать сложно или невозможно (это свзано не с архитектурой или закрытостью/монолитностью, а просто с отсутствием каких-то дополнительных специфических слов), но в целом юникод вполне можно использовать. Кроме того, ннкрон - это форт. А у форта все открыто для пользователя и при желании можно изменить любую часть системы или добавить любой новый функционал. Я часто использую юникод - и конвертирую в разные виды юникода, и произвожу замену в юникод строках через регулярные выражения - все работает как ожидается.
-

VoidVolker
- Site Admin
-
- Posts: 2907
- Joined: Tue, 25 Apr 2006, 17:56
by ebugusey » Sun, 14 Feb 2016, 22:24
VoidVolker wrote:Вообще-то, ннкрон создан на основе SP-Forth 3.75. А история SP-Forth насчитывает уже 24 года. Первая версия работала еще под мс-дос (1992). С появлением первых Windows SP-Forth был перенесен на новую платформу, а затем был переписан еще раз для работы в 32-битных системах. И в те далекие времени юникод не был так распространен, как сегодня. Принципиально юникод ничем не отличается от других кодировок и переписывать ннкрон для его поддержки не нужно. Да, я не спорю, в некоторых местах в ннкроне юникод использовать сложно или невозможно (это свзано не с архитектурой или закрытостью/монолитностью, а просто с отсутствием каких-то дополнительных специфических слов), но в целом юникод вполне можно использовать. Кроме того, ннкрон - это форт. А у форта все открыто для пользователя и при желании можно изменить любую часть системы или добавить любой новый функционал. Я часто использую юникод - и конвертирую в разные виды юникода, и произвожу замену в юникод строках через регулярные выражения - все работает как ожидается.
Полная поддержка, это когда я смогу модули в UTF-8 писать без BOM. Когда S" и операции со строками его будут поддерживать. Когда длина строки будет считаться не в байтах, а в графемах. Когда в регулярках \w будет соответствовать любой одной букве, а не только латинице, когда \b будет работать с русскими буквами. Нормальной поддержки юникода нет даже в текущей версии JavaScript, костыльная будет только к ES6. В Perl длина строк измеряется в code points, а не в графемах, но там хотя бы классы символов работают. В php и Ruby используется oniguruma, если я не ошибаюсь, и там тоже все не слава богу. Самая полная поддержка регулярок есть в PCRE, но если ваше приложение не поддерживает юникод, то оно вам будет абсолютно бесполезно. Переход на юникод это большая сложная работа. Сказать, что юникод ничем не отличается от прочих кодировок это, простите, все равно что в лужу пернуть. В том же с++ это сделано через костыльные отдельные фунции для работы с юникодом и использованию специальных литералов для обозначения строк в юникоде, вместо того чтобы добавить его поддержку на базовом уровне. Я считаю поддержка юникода это минимум необходимый для современного приложения. Если ваше приложение работает с файловой системой, то у него возникнут большие проблемы с файлами с именами в кодировке отличной от установленной в параметрах совместимости (попробуйте как-нибудь в nnCron обработать каталоги с японскими иероглифами). Если приложение обрабатывает тексты, тут тоже необходима поддержка юникода. Хотите i18n? Без юникода не обойтись. Хотите чтобы ваше приложение корректно отображалось на любой ОС с любой локалью? Добро пожаловать в мир юникода.
-
ebugusey
-
- Posts: 8
- Joined: Wed, 20 Jan 2016, 20:03
by spronkin » Mon, 29 Feb 2016, 03:59
VoidVolker wrote:- Code: Select all
S" Строка CP1251, конвертированная в UTF8" S>UNICODE UNICODE>UTF8 TYPE CR
- Code: Select all
S" Строка в CP1251, конвертированная в UTF8 и обратно" S>UNICODE UNICODE>UTF8 UTF8>UNICODE UNICODE>S TYPE CR
Вставка UTF8 в буфер обмена несколько сложнее будет. А какова задача в целом?
Хочу реализовать обработку текста UNICODE в кодировке UTF-8 через CLIPBOARD. Если я копирую текст "äd" в буфер обмена, то в обоих случаях при выводе на консоль он выглядит одинаково: - Code: Select all
CLIPBOARD TYPE CR ad Ok CLIPBOARD S>UNICODE UNICODE>UTF8 TYPE CR ad Ok
Я думаю дело не в консольном шрифте, так как в задаче получаю то же самое: - Code: Select all
Action: CLIPBOARD S>UNICODE UNICODE>UTF8 S" === clip ===" S+ \ извлекаем из буфера и добавляем текст SEND-KEYS: "^({INSERT})" \ копируем новое значение в буфер PAUSE: 100 CLIPBOARD S>UNICODE UNICODE>UTF8 S+ CLIPBOARD! \ объединяем все и помещаем снова в буфер BALLOON: "putclip" "Готово!"
Соответственно, если я вставляю в Akelpad результат, то буква "ä" выглядит как "a". 
-

spronkin
-
- Posts: 86
- Joined: Sun, 15 Jan 2012, 13:56
-
by VoidVolker » Mon, 29 Feb 2016, 08:59
UTF8 - это кодировка с переменным размером символов в байтах и первые 127 символов являются однобайтовыми и соответствуют ASCII.
-

VoidVolker
- Site Admin
-
- Posts: 2907
- Joined: Tue, 25 Apr 2006, 17:56
by spronkin » Mon, 29 Feb 2016, 21:55
VoidVolker wrote:UTF8 - это кодировка с переменным размером символов в байтах и первые 127 символов являются однобайтовыми и соответствуют ASCII.
Но символ а умлаут выходит за пределы 128-битного набора ASCII. Получается, что слово CLIPBOARD помещает на строковый стек текст из буфера обмена в кодировке CP1251 и не может работать с текстом в UTF-8? Тогда какой смысл в словах S>UNICODE и UNICODE>UTF8, дополнительная перекодировка получается? Или эти слова надо указывать до слова CLIPBOARD?
-

spronkin
-
- Posts: 86
- Joined: Sun, 15 Jan 2012, 13:56
-
by VoidVolker » Mon, 29 Feb 2016, 22:11
Заглянул в исходники: - Code: Select all
... CF_TEXT GetClipboardData ...
Да, текст из буфера приходит в ANSII кодировке и с юникодом в данном виде это все работать не будет, видимо.
-

VoidVolker
- Site Admin
-
- Posts: 2907
- Joined: Tue, 25 Apr 2006, 17:56
by spronkin » Mon, 29 Feb 2016, 22:35
Печалька. Ждем UNICODE версию nnCron 2.0! Может быть, там это будет реализовано. Также интересно было бы увидеть слово WatchSTDOUT, слушащее текст со стандартного вывода, например, при указании "… | nncron.exe" и кладущее на стек этот текст в виде строки в определенном месте Action.
PS: А CF_TEXT это однобайтный массив или что это за функция?
-

spronkin
-
- Posts: 86
- Joined: Sun, 15 Jan 2012, 13:56
-
by VoidVolker » Mon, 29 Feb 2016, 23:08
spronkin wrote:ечалька. Ждем UNICODE версию nnCron 2.0! Может быть, там это будет реализовано.
Ну вообще-то это совсем не нужно - ждать-то. Ибо все внутренности ннкрона открыты и можно изменить все что угодно и как угодно. Вопрос только во временных затратах и получении нужного результата. spronkin wrote:А CF_TEXT это однобайтный массив или что это за функция?
Обычная константа для Windows API. Заменил её на юникодный флаг - в целом работает, но этого недостаточно, т.к. надо менять код еще и в других местах в процедурах работы с буфером обмена, а для этого надо сначала в АПИ его разобраться.
-

VoidVolker
- Site Admin
-
- Posts: 2907
- Joined: Tue, 25 Apr 2006, 17:56
by dothen » Tue, 05 Apr 2016, 23:14
Может быть так - Code: Select all
<% \ http://www.nncron.ru/download/nnlib.zip \ nnlib.zip\~nn\lib\u\util\wstr.f \ nnlib.zip\~nn\lib\u\util\wz.f \ https://github.com/nnCron/nnCron/blob/master/src/clipboard2.f \ http://www.nncron.ru/download/nnsrc.zip \ nnsrc.zip\cron\clipboard2.f
13 CONSTANT CF_UNICODETEXT 2 CONSTANT GMEM_MOVEABLE 8192 CONSTANT GMEM_DDESHARE
: WCLIPBOARD@ ( -- wa wu ) GET-CB-MUTEX \ * <CLIPBOARD> @ 0= \ * IF FREE-<CLIPBOARD> 10 OpenClipboardWait IF CF_UNICODETEXT IsClipboardFormatAvailable IF CF_UNICODETEXT GetClipboardData ?DUP IF DUP GlobalLock WASCIIZ> MAX-CB-SIZE MIN DUP CELL+ GLOBAL WALLOCATE LOCAL THROW <CLIPBOARD> ! 2* >R <CLIPBOARD> @ R@ CMOVE 0 <CLIPBOARD> @ R> + W! GlobalUnlock DROP THEN ELSE \ S" CLIPBOARD: text unavailable." CUR-NODE LOG-NODE THEN CloseClipboard DROP ELSE CB-ERR1 THEN \ * THEN <CLIPBOARD> @ ?DUP IF WASCIIZ> ELSE PAD 0! PAD 0 THEN FREE-CB-MUTEX ;
: WCLIPBOARD! ( wa wu -- ) GET-CB-MUTEX 10 OpenClipboardWait IF EmptyClipboard DROP FREE-<CLIPBOARD> 2* DUP 2+ GMEM_MOVEABLE GMEM_DDESHARE OR GlobalAlloc ?DUP IF DUP GlobalLock 2SWAP ROT 2DUP + 0 SWAP W! SWAP CMOVE DUP GlobalUnlock DROP CF_UNICODETEXT SetClipboardData DROP ELSE 2DROP S" CLIPBOARD: not enough memory." CUR-NODE LOG-NODE THEN CloseClipboard DROP ELSE 2DROP CB-ERR1 THEN FREE-CB-MUTEX ; %>
#( task-test-WCLIPBOARD NoActive CREATE WSTRING \ Строка для примера 115 C, 0 C, 111 C, 0 C, 99 C, 0 C, 105 C, 0 C, 233 C, 0 C, 116 C, 0 C, 233 C, 0 C, 0 C, 0 C,
WINAPI: MessageBoxW user32.dll
: WPTYPE ( wa wu -- ) 2* PTYPE ;
: Out-Clip ( -- ) WCLIPBOARD@ WPTYPE CR 0 WCLIPBOARD@ DROP DUP 0 MessageBoxW DROP ; \ ----------------------------------------- Action: WSTRING WASCIIZ> WCLIPBOARD! 50 PAUSE Out-Clip WSTRING WASCIIZ> W" QWERTY" W+ WCLIPBOARD! Out-Clip WSTRING WASCIIZ> W" ЙЦУКЕН" W+ WCLIPBOARD! Out-Clip WCLIPBOARD@ UNICODE>S PTYPE CR )#
-
dothen
-
- Posts: 187
- Joined: Mon, 16 Mar 2015, 04:58
by dothen » Sat, 09 Apr 2016, 21:31
Выводим юникод в локальную консоль. - Code: Select all
#( task-test-WRITE-CONSOLE \ Юникод в консоль. Работает только в локальной консоли. NoActive
WINAPI: WriteConsoleW Kernel32.dll
: WRITE-CONSOLE ( wa wu -- ) 0 lpNumberOfBytesWritten 2SWAP SWAP H-STDOUT WriteConsoleW DROP ; Action:
\ Если кронтаб в кодировке ANSI W" йцукен" S" ЙЦУКЕН" S>UNICODE W+ WRITE-CONSOLE CR
\ Если кронтаб в кодировке UTF-8 в консоли выбрать шрифт Lucida Console S" société" S" «προέλευση»" S+ UTF8>UNICODE WRITE-CONSOLE CR )#
-
dothen
-
- Posts: 187
- Joined: Mon, 16 Mar 2015, 04:58
by ANR Daemon » Tue, 26 Apr 2016, 03:03
spronkin wrote:Я считаю, что обрабатывать текст в буфере обмена быстрее с той точки зрения, что текст находится не на диске, а в оперативной памяти
Вот только буфер обмена - это не просто кусок памяти. Это сервис. И до этого сервиса охочи не только вы. Если у вас, например, запущен какой-то офисный пакет, или, скажем, Punto Switcher, они мониторят буфер обмена, постоянно. Если они запущены оба, то мониторят они его ОБА. И КАЖДОЕ ИЗМЕНЕНИЕ БУФЕРА ОБМЕНА ОБРАБАТЫВАЕТСЯ ЭТОЙ КУЧЕЙ ПРОГРАММ. ЭТО ЧЁРТ ПОБЕРИ МЕДЛЕННО! СЕКУНДА НА КАЖДОЕ ИЗМЕНЕНИЕ! Заменить "А" на "Б" - секунда. Заменить десять "А" на шесть "Б" - 15 секунд. Если вам ДЕЙСТВИТЕЛЬНО нужно быстро работать со строками, то работайте с ними в ОБЫЧНОЙ памяти, а не в буфере обмена.
-
ANR Daemon
-
- Posts: 234
- Joined: Mon, 26 Feb 2007, 22:59
by spronkin » Thu, 10 Nov 2016, 19:38
Извините, что вновь поднимаю тему, но у меня возник вопрос по поводу работы со строками. Можно ли как-нибудь, минуя CLIPBOARD, перенаправить в задаче стандартный вывод консольных приложений, которые используются в слове START-APP(W) сразу на стек в виде строки? И потом уже брать этот текст со стека и обрабатывать его штатными средствами nncron. В настоящее время я делаю так: - Code: Select all
Action: CREATE buf_ex 1024 ALLOT START-APPW: "paste.exe | ... | ... | clip" CLIPBOARD buf_ex ZMOVE TMSG: "%CLIPBOARD%" 1
А хотелось бы напрямую, без CLIPBOARD. Тогда бы и задача выполнялась побыстрее, как говорит ANR Daemon. Если бы была консольная утилита, которая делает это сразу в cmd, - Code: Select all
START-APPW: "paste.exe | ... | ... | nstack"
PS: Может быть есть секретные параметры у слова START-APPW, которые позволяют это сделать? 
Last edited by spronkin on Thu, 10 Nov 2016, 21:39, edited 1 time in total.
-

spronkin
-
- Posts: 86
- Joined: Sun, 15 Jan 2012, 13:56
-
by VoidVolker » Thu, 10 Nov 2016, 21:12
В дистрибутиве СПФ есть как минимум одна библиотека для работы со стандартным вводом/выводом. Принципиально там ничего сверхсложного - все делается через доступный и документированный WINAPI, просто там как всегда несколько запутано и надо разбираться. Возможно либа сразу заработает, возможно нет и придется подправлять что-то.
-

VoidVolker
- Site Admin
-
- Posts: 2907
- Joined: Tue, 25 Apr 2006, 17:56
Return to nnCron forum (Russian)
Who is online
Users browsing this forum: No registered users and 5 guests
|
|