LINUX.ORG.RU

[C] [PCRE] Как получить результат компиляции регулярного выражения?

 ,


0

1

Здравствуйте!


Столкнулся сейчас с такой особенностью библиотеки PCRE. В PCRE есть основная функция:

// Функция pcre_compile компилирует регулярное выражение 
// во внутреннее представление библиотеки.
pcre *pcre_compile(const char *pattern, int options,
          const char **errptr, int *erroffset, 
          const unsigned char *tableptr);

Она возвращает ссылку на структуру pcre. Я хотел бы эти «промежуточные» данные куда-нибудь сохранить (типа что-то наподобие кеширования) чтобы лишний раз одну и ту же регулярку не компилировать во внутренне представление.

Чтобы сохранить, нужно иметь место, куда сохранять. Для начала примитивно - сохранить в переменную типа pcre. Добавляю в программу одну строку:

pcre regexpCompileData;

и компилирую. Получаю ошибку:

error: aggregate ‘pcre regexpCompileData’ has incomplete type and cannot be defined


Вопрос: как так хитро сделано, что нет доступа к типу, а есть доступ только к указателю на тип? Можно ли это как-то обойти чтобы вытянуть данные?

struct my_struct;

int main()
{
        struct my_struct *ptr;
        struct my_struct obj;
}
ttnl ★★★★★
()
Ответ на: комментарий от ttnl

То есть, о прекомплировании регулярок в PCRE можно забыть? Нужно постоянно тратить процессорные мощности на повторные действия?

webhamster
() автор топика
Ответ на: комментарий от webhamster

>То есть, о прекомплировании регулярок в PCRE можно забыть? Нужно постоянно тратить процессорные мощности на повторные действия?

Я не понимаю, в чем проблема сохранять этот указатель.

ttnl ★★★★★
()
Ответ на: комментарий от ttnl

>Я не понимаю, в чем проблема сохранять этот указатель.

в файл? :D

s0L
()
Ответ на: комментарий от ttnl

> Я не понимаю, в чем проблема сохранять этот указатель.

Когда несколько регулярок используется, где гарантия что указатель, возвращаемый функцией pcre_compile(), будет указывать на разные прекомпилированные данные?

webhamster
() автор топика
Ответ на: комментарий от webhamster

>Когда несколько регулярок используется, где гарантия что указатель, возвращаемый функцией pcre_compile(), будет указывать на разные прекомпилированные данные?

Думаю, про это должно быть написано в мане.

ttnl ★★★★★
()

Не до конца понять суть страданий, но попробую угадать что именно нужно:

- pcre regexpCompileData;
+ pcre *regexpCompileData;

Можно ли это как-то обойти чтобы вытянуть данные?

regexpCompileData->some_variable

Slavaz ★★★★★
()
Ответ на: комментарий от webhamster

Когда несколько регулярок используется, где гарантия что указатель, возвращаемый функцией pcre_compile(), будет указывать на разные прекомпилированные данные?

А после использования какого говноапи возникают такие опасения?

Begemoth ★★★★★
()

топикстартеру кернигана-ричи в школе не дают?

struct real_pcre; /* declaration; the definition is private */

typedef struct real_pcre pcre;

anonymous
()
Ответ на: комментарий от Slavaz

> Не до конца понять суть страданий, но попробую угадать что именно нужно:

- pcre regexpCompileData;

+ pcre *regexpCompileData;



Да в том то и дело что с указателями работает изначально, но вот подумал - а кто же память под данные выделяет при очередном вызове pcre_compile()? И как можно быть уверенным, что новые скомпилированные данные не наложаться на предыдущие?


Можно ли это как-то обойти чтобы вытянуть данные?

regexpCompileData->some_variable


Хм, и все время опасаться, что структура поменяется?

webhamster
() автор топика
Ответ на: комментарий от Begemoth

>> Когда несколько регулярок используется, где гарантия что указатель, возвращаемый функцией pcre_compile(), будет указывать на разные прекомпилированные данные?

А после использования какого говноапи возникают такие опасения?

pcre.h

webhamster
() автор топика
Ответ на: комментарий от anonymous

> топикстартеру кернигана-ричи в школе не дают?

struct real_pcre; /* declaration; the definition is private */
typedef struct real_pcre pcre;

Что ты хотел этим сказать?

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

webhamster
() автор топика
Ответ на: комментарий от geekless

> Расскажи, как продвигается пиление твоей утилиты.

Пилю, сейчас версия 0.10, я с помощью нее пишу сейчас.

Все так же на низком уровне опрашивает устройство ввода, осилить сбор сообщений со всех окон X не смог. Три дня потратил впустую на решение только этой проблемы. Не работает, и я забил, ибо меня трясет уже от ублюдочной документации на Api X11. Что она есть, что ее нет - толку никакого. Официальной документации на X11 вообще в инете нет, только потуги энтузиастов и коротенькие ман-странички.

webhamster
() автор топика
Ответ на: комментарий от webhamster

> осилить сбор сообщений со всех окон X не смог.

1. Цепляешь плагин к xneur.
2. xneur сливает в твой плагин все KeyPress и KeyRelease со всех окон.
3. ...
4. Профит!

В чем проблема-то? Нах париться с низкоуровневым API иксов, если всё уже сделано другими людьми.

меня трясет уже от ублюдочной документации на Api X11


Всё там нормально с документацией.

geekless ★★
()
Ответ на: комментарий от geekless

>> осилить сбор сообщений со всех окон X не смог.

1. Цепляешь плагин к xneur.
2. xneur сливает в твой плагин все KeyPress и KeyRelease со всех окон.
3. ...
4. Профит!

В чем проблема-то? Нах париться с низкоуровневым API иксов, если всё уже сделано другими людьми.

1. Я не люблю xneur.

2. В ранее приведенном тобой примере в Xneur я не увидел события удерживания клавиши. Следовательно, невозможно отличить чистое нажатие клавиши (простой тык) от удерживаемого.

3. Конфиг моей программы позволяет цепляться на любой девайс на любой поток данных, что позволяет переключать раскладку хоть педалью от джойстика.

4. Мне несложно добавить взятие потока событий не от девайса, а из X11, весь вопрос в том как это сделать. Пока никто внятно не написал как - этого функционала в моей программе не будет, и возвращаться к данному вопросу я небуду ибо и так потратил три дня.

webhamster
() автор топика
Ответ на: комментарий от webhamster

> 1. Я не люблю xneur.

Охрененный аргумент.

я не увидел события удерживания клавиши


Разумеется ты его не увидел, поскольку удержание клавиши — это не событие, а состояние. И в принципе не может быть событием, в любой реализации. man XQueryKeymap

Следовательно, невозможно отличить чистое нажатие клавиши (простой тык) от удерживаемого.


Если в течение n миллисекунд не пришло KeyRelease... ну ты понял, да?

из X11, весь вопрос в том как это сделать


Исходники xneur открывать пробовал? Там всё просто и понятно.
1. Следишь за изменением фокуса.
2. Слушаешь события для сфокусированного окна.
3. Польза!

Пока никто внятно не написал как


Алгоритм я изложил абзацем выше. Подробности, как обычно, в исходниках, на чистом, расовом Си.

geekless ★★
()
Ответ на: комментарий от geekless

> Разумеется ты его не увидел, поскольку удержание клавиши — это не событие, а состояние. И в принципе не может быть событием, в любой реализации. man XQueryKeymap

Ты не знаешь матчасть. Клавиатура на аппаратном уровне генерит скан-коды при зажатой клавише. И это даже настраивается в BIOS. Два параметра - сколько ждать до начала повторения символов, и сколько выжидать между повторяемыми символами. Первое число обычно 0,5-0,8 сек, второе - 0,05-0,1 сек.

Кстати клавиши-модификаторы работают точно так же как и обычные клавиши - при их зажатии они через 0,5 сек к примеру начинают отправлять на комп повторные коды.

Отправка сканкода - это событие, а не состояние.


Следовательно, невозможно отличить чистое нажатие клавиши (простой тык) от удерживаемого.


Если в течение n миллисекунд не пришло KeyRelease... ну ты понял, да?


Чему точно равно n на конкретном компьютере на конкретной клавиатуре? Если делать так, как ты предлагаешь, даже при правильном определении n и m ты получишь рассинхрон и глюки относительно аппаратуры, тем более в многозадачной среде, тем более нереального времени. Нафиг такое щастье нужно.

webhamster
() автор топика
Ответ на: комментарий от webhamster

Это ты не знаешь матчасть. Повторная генерация сканкода через промежутки времени нужна для эмуляции последовательности нажатий и отпусканий клавиши. В тех случаях, когда это имеет смысл, иксы генерируют соответствующую последовательность событий. Например, нажми q и получишь серию из KeyPress и KeyRelease.

К текущему состоянию клавиши это не относится ну просто никак.

Это не у иксов, это у тебя проблемы с различением фундаментальных понятий: события и состояния.

geekless ★★
()
Ответ на: комментарий от webhamster

Более того, я не могу даже представить, для чего тебе потребовалось такое извращение. Приведи конкретный use case, с реализацией которого у тебя возникли трудности.

geekless ★★
()
Ответ на: комментарий от geekless

> Приведи конкретный use case, с реализацией которого у тебя возникли трудности.

У меня нет никаких трудностей. Все что мне надо, у меня работает.

Но если ты хочешь чтоб в программе прявилась работа не с девайсами, а с сообщениями X11, то пожалуйста, мне это нетрудно добавить.

Присылаешь простейший рабочий пример, в котором программа собирает события клавиатуры со всех окон X11, и я добавлю функционал.

webhamster
() автор топика
Ответ на: комментарий от webhamster

в иксах нет такого понятие как удерживаемое автоповторение
точнее нет в протоколе - как оно есть на виндах

в иксах этот автоповтор делает тупой таймер
и различать - автопор это или несколько нажатий должен уже следующий уровень

зацени строки из wine - его дривера к иксам
#ifdef HAVE_XKB
if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
XkbSetDetectableAutoRepeat( data->display, True, NULL );
#endif

ae1234 ★★
()
Ответ на: комментарий от geekless

>> Присылаешь простейший рабочий пример, в котором программа собирает события клавиатуры со всех окон X11

http://xneur.ru/downloads/

Что ты этот xneur все пихаешь. Если не можешь сделать простейший пример из одного main.cpp, в котором идет сбор событий X11, то кончай троллить здесь и в других темах.

webhamster
() автор топика
Ответ на: комментарий от webhamster

Ты ССЗБ не слушающий умных людей, которые тебе пытаются объяснить, как решить твою проблему правильно.

Если не можешь сделать простейший пример из одного main.cpp, в котором идет сбор событий X11

А мне это надо? Достаточно уже того, что я трачу время, объясняя тебе как в иксах обработать ввод, и какие исходники почитать, чтобы посмотреть, как это работает.

Если ты не осилил прочитать полтора коротких файла в xneur, которые имеют отношение к предмету, то чьи это проблемы? Точно не мои.

geekless ★★
()
Ответ на: комментарий от geekless

> Ты ССЗБ не слушающий умных людей, которые тебе пытаются объяснить, как решить твою проблему правильно.

Она у меня уже решена, спасибо.

webhamster
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.