libag — знаменитый «Искатель серебра», но библиотека
Несколько недель назад друг спросил меня, знаю ли я какой-нибудь инструмент для рекурсивного поиска по регулярным выражениям в текстовых и двоичных файлах. Мне сразу пришло на ум Ag, но, к сожалению, Ag(1) — это программа, а не библиотека.
Хотя это и не невозможно, анализ выходных данных Ag может оказаться довольно головной болью, а создание нового процесса для каждого поиска кажется утомительным. Подобные инструменты, такие как ripgrep(1), могут выводить данные в формате JSON, что, безусловно, значительно упрощает задачу, но мы все еще говорим о создании процессов и анализе выходных данных.
Так родился libag. Libag позволяет вам использовать поисковую систему (и ее возможности), но правильно (или почти правильно).
Libag призван быть максимально простым и поэтому делит процесс поиска на три простых шага:
Инициализируйте все внутренние структуры Ag (через ag_init()
).
Выполняйте столько поисков, сколько захотите (с помощью ag_search()
).
Очистите ресурсы (с помощью ag_finish()
).
Настройки пользовательского поиска выполняются с помощью ag_init_config()
и ag_set_config()
. Результатом является список структуры ag_result*, который содержит файл, список совпадений (содержащий совпадение и смещения файлов, соответствующие совпадению) и флаги.
(Полные примеры можно найти в примерах/)
#include <libag.h>
...
struct ag_result * * results ;
size_t nresults ;
char * query = "foo" ;
char * paths [ 1 ] = { "." };
/* Initiate Ag library with default options. */
ag_init ();
/* Searches for foo in the current path. */
results = ag_search ( query , 1 , paths , & nresults );
if (! results ) {
printf ( "No result foundn" );
return ( 1 );
}
printf ( "%zu results found\n" , nresults );
/* Show them on the screen, if any. */
for ( size_t i = 0 ; i < nresults ; i ++ ) {
for ( size_t j = 0 ; j < results [ i ] -> nmatches ; j ++ ) {
printf ( "file: %s, match: %sn" ,
results [ i ] -> file , results [ i ] -> matches [ j ] -> match ,
}
}
/* Free all results. */
ag_free_all_results ( results , nresults );
/* Release Ag resources. */
ag_finish ();
...
Libag намерен поддерживать все функции (в стадии разработки) ag (или, по крайней мере, те, которые имеют смысл для библиотеки). Кроме того, он обеспечивает детальный контроль над рабочими потоками с помощью ag_start_workers()
и ag_stop_workers()
(более подробную информацию см. в документации).
Libag имеет (экспериментальную) поддержку привязок к другим языкам программирования: Python и Node.js. Дополнительные сведения и более подробную документацию см. в разделах привязки/python и привязки/javascript.
Libag требует тех же зависимостей, что и компилятор ag:c99 и библиотеки: zlib, lzma и pcre. Эти библиотеки можно устанавливать по одной или с помощью вашего менеджера пакетов.
Для дистрибутивов, подобных Debian, что-то вроде:
$ sudo apt install libpcre3-dev zlib1g-dev liblzma-dev
(или следуйте рекомендациям Ag здесь)
Как только зависимости будут устранены, клонируйте репозиторий и выполните сборку. Libag поддерживает Makefile и CMake. Выберите тот, который лучше всего соответствует вашим потребностям:
$ git clone https://github.com/Theldus/libag.git
$ cd libag/
$ make -j4
# Optionally (if you want to install):
$ make install # (PREFIX and DESTDIR allowed here, defaults to /usr/local/)
$ mkdir build/ && cd build/
$ cmake .. -DCMAKE_BUILD_TYPE=Release
$ make -j4
# Optionally (if you want to install):
$ make install
Подробную документацию по каждой доступной процедуре можно найти на страницах руководства. Кроме того, исходный код подробно комментируется (libag.h обязателен к прочтению!). Документацию по привязкам и примеры можно найти здесь.
Полные примеры также доступны в папке example/ и автоматически собираются вместе с библиотекой для вашего удобства ;-).
Libag всегда открыт для сообщества и готов принять вклад, будь то проблемы, документация, тестирование, новые функции, исправления ошибок, опечатки и т. д. Добро пожаловать на борт.
Libag лицензируется по лицензии Apache v2.