LINUX.ORG.RU

Сообщения kawaii_neko

 

libopts - как оно?

Форум — Development

В рамках погружения в глубокие слои свободы в разработке программного обеспечения, хочу попробовать вместо тупого getopt-а воспользоваться фреймворком для обработки опций командной строки (libopts). Решил начать с ознакомления с лицензией:

Files: autoopts/* Copyright: (C) 1992-2015 by Bruce Korb License: LGPL-3+ or Modified_BSD .... Files: autoopts/stdnoreturn.in.h Copyright: Copyright 2012-2013 Free Software Foundation, Inc. License: LGPL-2.1+

stdnoreturn.in.h используется в autoopts/autoopts.h, который участвует только в процессе сборки libopts. Значит ли это, что я могу безнаказанно и самозабвенно проприетариться в libopts и меня за это никто не осудит?

На самом деле, я далек от всей этой лицензионной свистопляски и просто хочу украсить свой гитхабчик примером работы с этой библиотекой, чтобы позже копипастить код оттуда направо и налево — то есть, WTFPL во все поля. Это законно?

Ну и вообще, стоит ли овчинка выделки — хватит ли мне этого фреймворка на все случаи жизни, или лучше ограничится getopt/argp/boost::program_options (последнее — щютка, если кто не понял)?

 , ,

kawaii_neko
()

Скрыть «внутренние символы» в статической библиотеке

Форум — Development

Допустим, есть некая библиотека, использующая внутри себя патченный libcrypto. Если бы речь шла о динамической библиотеке, все просто: компилируем libcrypto с PIC, линкуемся с шаренной библиотекой, скрывая ненужные символы через linker script. А если такой же трюк требует провернуть для статической библиотеки?

Пример для наглядности: берем SHA1_Init(SHA_CTX *c), добавляем ей какой-нибудь параметр int SHA1_Init(SHA_CTX *c, int param), собираем libcrypto.a ну и свою libyoba.a. Далее, если положить все (или только нужные) объектные файлы или libcrypto.a в libyoba.a, то при линковке с yoba с приложением, использующим SHA1_Init, в зависимости от порядка -lyoba -lcrypto, все результирущее приложение получит либо патченный SHA1_Init, либо его оригинальную версию. А хотелось бы, чтобы патченный SHA1_Init оставался исключительно внутри libyoba.a.

Понимаю, что это решается банальным переименованием, но уж больно много всего переименовывать в libcrypto придется.

 

kawaii_neko
()

Как в C++ принято скрывать детали реализации?

Форум — Development

Проблема: проект конпелируется в лучших традициях по 15 минут в 8 потоков. Изи солюшн: перестать писать код в хидерах и начать инстанциировать в cpp — это все и собаке понятно.

Но вот при попытке сделать так натыкаюсь на грабли: объекты соержат данные, объявления которых приводят к жуткой шаблонной оргии. Хочется а) сохранить статичный интерфейс (никаких virtual = 0); б) не связываться с pimpl, ибо уродство.

В любимой сишечке все делается просто и элегантно:

#ifndef LIBRARY_SOURCE
typedef void *INTERFACE;
#endif

INTERFACE* interface_new(int param1, int param2);
void inferface_free(INTERFACE *iface);
int interface_method1(INTERFACE *iface, int arg);
/* etc */
В C++ это смотрится вроде как убого, потому что можно вызывать статические методы через точку или стрелочку, но объявить такой объект в хидере нельзя.

pimpl убого по определению и даже не рассматривается, абстрактный базовый класс связывает по рукам и ногам и вообще заставляет писать лишний и ненужный код. Плюнуть на крестоахинею и писать как диды завещали (бонусом сделать все extern C и наслаждаться изи биндингами ко всему, что движется), или есть что-то чего я не знаю?

P. S. самое близкое, но убогое — это

// header
struct Interface {
protected:
public:
  Interface() = delete;
  Interface(const Interface&) = delete;
  ~Interface();

  int method1(int arg1, int arg2);
  static Interface *create(int param1, int param2);
}

// cpp
struct Implementation : public Interface {
  CTemplate<is<shit>,and<urine>> field;
  /* пихаем всю дейту */
  Implementation(int param1, int param2) { ... }
  int method1(int arg1, int arg2) { ... }
};

Interface* Interface::create(int param1, int param2) {
  return new Implementation(param1, param2);
}

/* извращенный pimpl, можно было бы напрямую работать с this, интерпретируя его как Implementation */
int Interface::method1(int arg1, int arg2)
{
  return reinterpret_cast<Implementation*>(this)->method1(arg1, arg2);
}

/* вишенка на торте: бесконечная рекурсия, как я люблю, х-з че делать */
Interface::~Interface()
{
  reinterpret_cast<Implementation*>(this)::~Implementation();
}

Че делать-то?

Перемещено leave из desktop

 ,

kawaii_neko
()

youcompleteme перестал работать

Форум — Development

Обновил libclang до 3.9.1 и внезапно обнаружил, что youcompleteme больше не работает. Подробности сообщений об ошибке, как всегда, можно только позавидовать:

POST /semantic_completion_available HTTP/1.1
Host: 127.0.0.1:36270
Content-Length: 231
x-ycm-hmac: shutHbEv/Usi+MC3rzkNTxqIuuthtFO870iPBu0YZXs=
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.9.1
Connection: keep-alive
content-type: application/json

{"file_data": {"/tmp/1.c": {"filetypes": ["c"], "contents": "struct A {\n    int field;\n};\n\nint main()\n{\n    struct A a;\n    a.\n    return 0;\n}\n"}}, "line_num": 8, "filetypes": "c", "column_num": 7, "filepath": "/tmp/1.c"}
HTTP/1.1 500 INTERNAL SERVER ERROR
Content-Length: 80
Content-Type: text/html; charset=UTF-8
Date: Tue, 14 Feb 2017 08:01:07 GMT
Server: waitress

<h1>Critical error while processing request: /semantic_completion_available</h1>

Ну и в логе

2017-02-14 11:04:39,676 - ERROR - Error while handling server response
Traceback (most recent call last):
  File "/usr/share/vim/vimfiles/autoload/../python/ycm/client/base_request.py", line 196, in HandleServerException
    yield
  File "/usr/share/vim/vimfiles/autoload/../python/ycm/client/ycmd_keepalive.py", line 50, in _ThreadMain
    BaseRequest.GetDataFromHandler( 'healthy' )
  File "/usr/share/vim/vimfiles/autoload/../python/ycm/client/base_request.py", line 74, in GetDataFromHandler
    timeout ) )
  File "/usr/share/vim/vimfiles/autoload/../python/ycm/client/base_request.py", line 163, in JsonFromFuture
    _ValidateResponseObject( response )
  File "/usr/share/vim/vimfiles/autoload/../python/ycm/client/base_request.py", line 239, in _ValidateResponseObject
    their_hmac = ToBytes( b64decode( response.headers[ _HMAC_HEADER ] ) )
  File "/usr/share/vim/vimfiles/third_party/ycmd/third_party/requests/requests/structures.py", line 54, in __getitem__
    return self._store[key.lower()][1]
KeyError: u'x-ycm-hmac'
В какую сторону копать?

 ,

kawaii_neko
()

ncurses update hell, или что хочет от меня portage?

Форум — Desktop

Внезапно обнаружил, что не могу обновить мир, потому что какой-то упырь-пакет хочет ncurses-6 (который я замаскировал в прошлый раз, ибо времени резолвить все всплывшие говнозависимости не было).

Теперь:

# emerge -1pv --verbose-conflicts ncurses

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild     U  ] sys-libs/ncurses-6.0-r1:0/6::gentoo [5.9-r5:0/5::gentoo] USE="cxx gpm unicode -ada -debug -doc -minimal -profile -static-libs {-test%} -threads% -tinfo -trace" ABI_X86="32 (64) (-x32)" 3059 KiB
[ebuild  r  U  ] sys-process/procps-3.3.12:0/5::gentoo [3.3.11-r3:0/5::gentoo] USE="kill ncurses nls unicode -modern-top (-selinux) -static-libs -systemd {-test}" 826 KiB
[ebuild  rR    ] net-misc/telnet-bsd-1.2-r1::gentoo  USE="nls -xinetd" 0 KiB

Total: 3 packages (2 upgrades, 1 reinstall), Size of downloads: 3885 KiB

!!! Multiple package instances within a single package slot have been pulled
!!! into the dependency graph, resulting in a slot conflict:

sys-libs/ncurses:0

  (sys-libs/ncurses-6.0-r1:0/6::gentoo, ebuild scheduled for merge) pulled in by
    sys-libs/ncurses (Argument)

  (sys-libs/ncurses-5.9-r5:0/5::gentoo, installed) pulled in by
    >=sys-libs/ncurses-5.7-r7:0/5= required by (sys-process/psmisc-22.21-r3:0/0::gentoo, installed)
                             ^^^^^                                                                                                     
    sys-libs/ncurses:0/5= required by (dev-scheme/guile-2.0.13:12/22::gentoo, installed)
                    ^^^^^                                                                                                   
    >=sys-libs/ncurses-5.2-r2:0/5= required by (sys-devel/gdb-7.10.1:0/0::gentoo, installed)
                             ^^^^^                                                                                              
    >=sys-libs/ncurses-5.9-r3:0/5=[abi_x86_32(-)] required by (sys-boot/grub-0.97-r16:0/0::gentoo, installed)
                             ^^^^^                                                                                                               
    sys-libs/ncurses:0/5= required by (media-video/mplayer-1.3.0:0/0::gentoo, installed)
                    ^^^^^                                                                                                   
    sys-libs/ncurses:0/5=[unicode] required by (net-im/pidgin-2.10.12-r2:0/0::gentoo, installed)
                    ^^^^^                                                                                                           
    >=sys-libs/ncurses-5.2:0/5= required by (app-misc/screen-4.3.1-r1:0/0::gentoo, installed)
                          ^^^^^                                                                                                  
    >=sys-libs/ncurses-5.7-r7:0/5= required by (media-sound/lame-3.99.5-r1:0/0::gentoo, installed)
                             ^^^^^                                                                                                    
    sys-libs/ncurses:0/5= required by (sys-apps/openrc-0.21.7:0/0::gentoo, installed)
                    ^^^^^                                                                                                
    >=sys-libs/ncurses-5.9-r3:0/5=[abi_x86_64(-)] required by (sys-devel/llvm-3.8.0-r2:0/3.8.0::gentoo, installed)
                             ^^^^^                                                                                                                    
    >=sys-libs/ncurses-5.2:0/5= required by (sys-apps/less-481:0/0::gentoo, installed)
                          ^^^^^                                                                                           
    >=sys-libs/ncurses-5.7-r7:0/5= required by (media-sound/alsa-utils-1.0.29:0.9/0.9::gentoo, installed)
                             ^^^^^                                                                                                           
    sys-libs/ncurses:0/5= required by (app-text/hunspell-1.3.3:0/0::gentoo, installed)
                    ^^^^^                                                                                                 
    sys-libs/ncurses:0/5= required by (app-misc/mc-4.8.17:0/0::gentoo, installed)
                    ^^^^^                                                                                            
    sys-libs/ncurses:0/5= required by (x11-libs/vte-0.28.2-r207:0/0::gentoo, installed)
                    ^^^^^                                                                                                  
    >=sys-libs/ncurses-5.2-r2:0/5= required by (app-shells/bash-4.3_p48:0/0::gentoo, installed)
                             ^^^^^                                                                                                 
    >=sys-libs/ncurses-5.2-r2:0/5=[unicode] required by (sys-apps/util-linux-2.26.2:0/0::gentoo, install

Естественно, старый добрый рецепт «добавить в пересборку все, что вызывает конфликты» не помогает. Я крайне близок к установке ubuntu глобальному USE=-ncurses, но как-то не хочется лишаться top.

 ,

kawaii_neko
()

Может ли встроенное видео быть полезным?

Форум — Talks

На десктопе при использовании дискретной видеокарты?

 

kawaii_neko
()

Частично прозрачный фон окна

Форум — Development

Можно ли в Qt создать форму с альфа-каналом, который будет корректно обработан копозитором, в результате чего можно будет сделать некоторые области основного окна «чуть более прозрачными, чем прочие»?

Знаю, что есть color key transparency и можно задать «прозрачность» всего окна, но насчет индивидуальных областей ничего не нашел.

Интересует не Qt-шный композитинг виджетов, в котором можно все, а именно «видеть содержимое под главным окном».

 

kawaii_neko
()

Ушат помоев в сторону крестолюбов

Форум — Development

Восседая в уютненьком кресле с чашечкой сладкого чая, внезапно ощутил приток жопной боли напополам с лирическим настроением и решил излить сию благодать куда руки дотянулись.

Последние 7 лет я пишу сугубо на C, и только под Linux (да, да -std=gnu99 и accept4, dup3, __attribute__((cleanup(dtor))) и прочие приятности, позволяющие сделать волосы шелковистее на 15.5%) и не понимаю, для чего вообще нужен C++? То, что на сишке делается красиво и элегантно, в крестах напоминает соитие парализованных дцпшников (к сожалению, утерял картинку, но именно этот образ всплывает в голове, когда вижу очередную порцию крестолапши).

Давайте посмотрим на типичного C++ разработчика: он использует STL, boost, многие любят Qt (не только для GUI), якобы чтобы «писать кроссплатформенный код». В итоге болезный не знает током ни WinAPI, ни POSIX — ничерта. Он абсолютно не разбирается, как работает целевая система, для которой пишет код! Крестокодер просто не осознает, какой лютый ужас кроется за его любимыми iostream-ами, какое лютое говно лежит в boost::filesystem::path, насколько убого-низкоуровневым является boost::asio в 2016 году.

Только крестораб может эпично обосраться и просадить производительность, забыв передавать по ссылке параметры для «горячих» функций (то есть, просто забыв написать «&» в нужном месте).

Также эти убогие завистливо смотрят на type inference в языках, проектировавшихся не как «C на стероидах», и в ответ начинают лепить template и auto не к месту, от чего код адово пухнет и даже IDE перестает его понимать.

Серьезно, просто прекратите писать на этом языке. В следующий раз, начиная новый проект, выберите java (щютка)/go/swift/rust/c. Прекратите насиловать труп и отравлять зловонием все вокруг!

Перемещено true_admin из talks

 , , ловите наркомана,

kawaii_neko
()

Готов для десктопа

Форум — Talks

Довольно длительное время сидел в дуалбутной винде, с виндовым firefox-ом, обмазанным всякими плагинами «чтоб youtube смотреть и не тормозило».

Сейчас решил компильнуть мир немного обновиться. Обновил флеш до 24-й версии, зашел на парочку тяжелых сайтов, и просто не узнал FF — он летает! В youtube скроллинг плавный, видео играются и не сильно нагружают CPU.

Но самое главное, браузер-то работает ощутимо быстрее, чем в windows. И WM такой удобный, в отличие от виндоговна (чего только шизанутое поведение Alt-Tab-а на полноэкранных DirectX играх приложениях стоит).

Да хрен с ним, с браузером. Понятно, чем занята система: если я ничего не делаю, в системе полтора процесса, не считая kworker-ов. Если в терминале десяток вкладок — будет десяток bash-ей. И, черт возьми, как это приятно, когда нет непонятных говносервисов, внезапного громкого насилия над жестким диском, если отойти минут на 5.

А софт? Весь софт ставится и обновляется легким движением руки из репозиториев, со всеми зависимостями, в автоматическом режиме без этих бесконечно-мудацких «next-next-are-you-sure».

Неужели наконец-то наступил светлый день, когда Linux готов для десктопа?

 , ,

kawaii_neko
()

bash + while + mplayer = FAIL???

Форум — General

Выпаршиваю URL-ы для проигрывания страницы и через while read url подаю их на вход mplayer-у. В итоге цикл завершается на первой же итерации. Заменяем mplayer на ffplay => все ок.

В какую сторону копать?

# mplayer завершается и цикл не идет дальше
curl http://www.divx.com/en/devices/profiles/video | grep -Eo 'href=.http[^"]*' | sed -nre 's/^href="(.*\.divx)$/\1/p' | while read url; do mplayer $url; done
# ffplay, mpv отрабатывают без проблем
curl http://www.divx.com/en/devices/profiles/video | grep -Eo 'href=.http[^"]*' | sed -nre 's/^href="(.*\.divx)$/\1/p' | while read url; do ffplay $url; done

 ,

kawaii_neko
()

Насколько порочно такое использование union-ов?

Форум — Development

По стандарту из union можно писать только то поле, которое было в него записано последним. А если речь идет о структурах?

struct type_a {
  int field1;
  char field2;
};

struct type_b {
  struct type_a a;
  double field3;
};

void do_a(struct type_a *a);
void do_b(struct type_b *b);

typedef union {
  struct type_a a;
  struct type_b b;
} super_type;

/* x->b гарантированно был инициализирован */
void do_c(super_type *x) {
  do_a(&x->a);
  do_b(&x->b);
}

Или вообще вот так (при условии что безымянная структура внутри union-а всегда совпадает с S):

struct S {
  char field1;
  int field2;
};

void do_S(struct S *s);

struct M {
  double x, y;
  union {
    struct {
      char field1;
      int field2;
    };
    struct S s;
  };
};

void do_M(struct M *m)
{
  m->field1 = '5';
  m->field2 = 5;
  do_S(&m->s);
}

 

kawaii_neko
()

Кодогенерация C

Форум — Development

Не далее чем вчера, находясь под впечатлением от http://www.computerra.ru/65749/steps/ (в частности, TCP стек в 160 строк), я озаботился поиском вменяемых средств кодогенерации с выводом в сишку и не обнаружил особого разнообразия. Конечно, есть просто обалденные bison, ragel, да тот же protobuf, наконец — но какого-то generic решения я не нашел.

Точнее говоря, есть autogen и m4, но они настолько инопланетными, что идея запилить свой транслятор на сишке, используя bison + flex, не кажется чем-то диким.

Может многоуважаемый all подскажет что-то новое?

P. S. основное пожелание: чтобы входной DSL был легко читаем и модифицируем без изучения тотально нового языка.

 , ,

kawaii_neko
()

Не могу примонтировать NTFS-раздел в ro ядерным ntfs-драйвером

Форум — Desktop

После обновления системы для монтирования ntfs-разделов всегда используется ntfs-3g. А мне, в общем-то большую часть времени нужен только RO доступ к общим данным.

Вот строчки в fstab:

/dev/sdc1	/mnt/win_c	ntfs	ro,showexec,noauto,users	0 0
/dev/sdc5	/mnt/win_d	ntfs	ro,showexec,noauto,users	0 0

А вот что получается:

$ ps awux | grep ntfs
root      4144  0.0  0.0  16840  1896 ?        Ss   13:15   0:00 /usr/sbin/mount.ntfs /dev/sdc1 /mnt/win_c -o ro,noexec,nosuid,nodev,showexec,users
root      4152  0.0  0.0  16840  1952 ?        Ss   13:15   0:00 /usr/sbin/mount.ntfs /dev/sdc5 /mnt/win_d -o ro,noexec,nosuid,nodev,showexec,users

Естественно, ntfs-драйвер в ядре есть:

$ find /lib/modules/ -name 'ntfs*'
/lib/modules/4.4.6-gentoo/kernel/fs/ntfs
/lib/modules/4.4.6-gentoo/kernel/fs/ntfs/ntfs.ko

И он предоставляет файловую систему ntfs:

$ cat /proc/filesystems | grep ntfs
	ntfs

И тем не менее

$ mount | grep sdc
/dev/sdc1 on /mnt/win_c type fuseblk (ro,nosuid,nodev,noexec,relatime,user_id=0,group_id=0,allow_other,blksize=4096)
/dev/sdc5 on /mnt/win_d type fuseblk (ro,nosuid,nodev,noexec,relatime,user_id=0,group_id=0,allow_other,blksize=4096)

У меня складывается ощущение, что виноват mount, который использует mount.ntfs. Раньше это совершенно точно называлось mount.ntfs3g. Как быть?

 , ,

kawaii_neko
()

EFI => MBR

Форум — Linux-install

По дурости решил накатить уютненькую генточку с поддержкой UEFI. Разметил диск в GPT, распаковал stage3, собрал кучу всего. Но вот засада: не могу добиться загрузки ядра. Использую rEFIND — после выбора ядра «что-то происходит», а затем reboot (я так полагаю, что случается паника). При этом ядро на экран вообще ничего не выводит.

Эта петушиная феерия маркетоидной бредотехнологии под названием EFI меня порядком утомила, поэтому просто хочу спросить: каким образом преобразовать GPT => MBR без потери данных и вернуться в свой уютненький grub-0.97? Compatibility mode поддерживается материнкой (собственно, и гружусь с флешки безо всяких efi).

 ,

kawaii_neko
()

Посоветуйте материнскую плату на сокет LGA1151

Форум — Linux-hardware

Задумал делать апгрейд. С процессором определиться было довольно легко: Core i7 6700 (без K, чтобы не перегревал мне помещение в жаркое лето) —, а вот с материнскими платами какие-то непонятки.

Хочу мигрировать без смены носителей, поэтому хочется поддержки Legacy mode, а выяснить, поддерживается ли он ASUS Z170-P D3 из интернета не получается. Может кто поделится историей успеха на сокете LGA1151 + MBR? А то как-то не хочется прийти к патовой ситуации, когда нельзя загрузиться ни на новом, ни на старом железе.

 , ,

kawaii_neko
()

fish: && и ||

Форум — Desktop

Пробовал эту хипстерскую поделку неоднократно, и каждый раз, плюясь, сносил, ибо

make && ./binary
в стотыщмильонов раз быстрее набивается, чем
make; and ./binary

Поскольку ребята кладут болт эту пользовательскую хотелку, взял инициативу в свои шаловливые лапки.

Слегка ломается подсветка синтаксиса, но мне как-то фиолетово, каким цветом «&&» и «||» отображаются до тех пор, пока работают, как мне надо.

 

kawaii_neko
()

Вернуть сложный lisp-объект из сишной функции

Форум — Development

Допустим, у нас есть сложная структура данных, которая представима в виде s-expressions, внутри которых встречаются самые разнообразные атомы, в том числе keywords и symbols. Вопрос: позволяет ли какая-либо из реализаций CL провернуть подобное?

Уверен, что ecl может, но относительно интересующих меня clozurecl и clisp никак не могу накопать в хидерах что-то похожее.

Конечно же, можно взять cffi, через defcstruct/defcunion «открыть скобочному миру» сишные структуры, и в самом лиспе преобразовать это в нужный вид, но выглядит

  • костыльно (int => keyword/symbol)
  • небыстро
  • двойная работа: генерируем списки в сишечке, чтобы пройтись по ним лиспом и сделать нормальные cons-ы

 ,

kawaii_neko
()

Посоветуйте язык с мощным консольным repl-ом

Форум — Development

Есть некоторое внутреннее API, которое хочется «оживить» с помощью настоящего языка программирования, ибо конвейеры из grep/sed/awk с cli-тулзой тяжелы в написании/понимании/эксплуатации. В связи с этим хочется иметь язык, в который я впихну имеющиеся вызовы, красиво их оберну и буду наслаждаться использованием.

Но есть одна проблема: я не хочу терять очень удобный cli с автокомплитом, который я таки наваял, но также я не хочу переизобретать cli для языкового биндинга.

В идеале хотелось бы, чтобы язык: - имел именованные параметры у функций - имел консольный REPL с историей с действительно умным дополнением (в частности, предлагал эти самые именованные параметры) - имел выразительные структуры данных (вот по этому пункту лисп с его s-exp'ами явный фаворит, т. к. через keyword'ы + s-exp выражается практически вся моя предметная область) - дружил с C++ (желательно без swig, т. к. на моей памяти отображение 1-в-1 ни разу не выглядело «родным и удобным» для целевого языка) на самом примитивном уровне: временем жизни плюсовых объектов я хочу управлять сам

О чем слышал:

  • для python-а есть ipython, с двумя вариантами: браузерная и qt-шная консоль — выглядит вкусно, но в ssh с таким не побалуешь
  • для lisp-а есть slime, однако комплит в нем подозрительно тупой:
    (defun my-sum (&key arg-1 arg-2)
      (+ arg-1 arg-2))
    (my-sum :arg-1 1 :arg-2 2)
    
    во-первых, arg-1 и arg-2 не предлагаются к дополнению внутри функции (точнее говоря, предлагается куча разного всякого г-на, на фоне которых аргументы теряются) во-вторых, при вызове этой функции keyword-ы для именованных аргументов также предлагаются в последнюю очередь

В каком направлении можно покопать? Или плюнуть на все, писать свой парсер для s-exp'ов к readline и костылить нужное мне дополнение полностью вручную (выглядит жуть как геморно, я лучше с sed/grep/awk посношаюсь)?

 ,

kawaii_neko
()

Syntax-aware autocomplete

Форум — Development

Допустим, у нас есть лексер и грамматика некоего DSL. Мы хотим сделать хорошую интерактивную среду, как у «взрослых»: чтобы аргументы у функций предлагались, исходя из контекста.

То есть, если есть правило

let_stmnt:
  TOK_LET TOK_IDENTIFIER TOK_ASSIGN expr;
то хотелось бы, чтобы нажатие на <TAB> при нахождении в месте ввода идентификатора понимало, что сейчас мы хотим предложить автокомплит по известным именам переменных.

Иными словами, мне нужно каким-то образом достучаться до всех возможных незавершенных вариантов разбора части набранного выражения. Пока я не придумал ничего лучше, как

let_stmnt:
  TOK_LET variable TOK_ASSIGN expr;

variable:
  TOK_IDENTIFIER { add_completion(COML_VAR, @$); }
Где add_completion добавляет в список возможных вариантов дополнений, что в таких-то позициях строки можно дополнять имя переменной. По мне, так выглядит как-то очень костыльно, ведь чем удобнее захочется сделать грамматику, тем больше правил будут давать «мусорные» варианты дополнения.

В процессе гугления находил только рекомендации использовать push parser для такого, но без конкретики или примеров.

Ну и вообще, для «дружественного DSL» хотелось бы более понятных сообщений об ошибке, нежели «expected expr», ведь из частично заматчившихся правил можно сузить набор возможных на данной позиции лексем.

 ,

kawaii_neko
()

non-blocking splice + EPOLLET

Форум — Development

Допустим, я хочу странного: использовать edge-triggered epoll (всегда мечтал, но руки все не доходили) + splice для работы с диском (отправка/получение файлов). При этом splice между (pipe => disk) и (net => pipe) происходят в отдельных тредах (в linux же не могут завести человеческое дисковое aio).

Проблема в том, что когда splice возвращает EAGAIN как-то очень нетривиально догадаться, кто виноват. Если использовать level-triggered IO, все просто: мониторим pipe и source/destination socket на готовность к чтению/записи и пишем/читаем. Получили EAGAIN — не паримся и уходим в epoll, позже видно будет, кто виноват.

Если использовать ioctl, чтобы понять, не переполнился ли пайп, можно наступить на race (splice file => pipe и pipe => socket происходят в разных потоках). Если узнать максимальный размер буфера pipe, также пойдут race, потому как операции «атомарно сделать splice и изменить userspace счетчик» не завезли. Можно обмазаться mutex'ами, но это убьет производительность (splice сможет делать только один поток).

С level-triggered все просто: получил событие, позвал splice и если наткнулся на EAGAIN, значит виновата «другая сторона», т. к. файловый дескриптор готов к чтению записи — гарантировано epoll'ом. Но level-triggered делают все, и в нем время от времени придется делать EPOLL_CTL_DEL. В edge-triggered не нужно в принципе изменять набор дескрипторов, но splice нужно проводить до победного EAGAIN, а там уже фиг поймешь, кто виноват.

Может есть какой-то красивый трюк, о котором никто не пишет?

P. S. Любители nginx и прочих готовых «быстрых веб-серверов» идут лесом — у меня душа странного требует.

 

kawaii_neko
()

RSS подписка на новые темы