libag - O famoso The Silver Searcher, mas biblioteca
Algumas semanas atrás, um amigo me perguntou se eu conhecia alguma ferramenta para pesquisa recursiva de expressões regulares em arquivos de texto e binários. Ag imediatamente me veio à mente, mas infelizmente ag(1) é um programa, não uma biblioteca.
Embora não seja impossível, analisar a saída Ag seria uma dor de cabeça, além de gerar um novo processo para cada pesquisa parecer tedioso. Ferramentas semelhantes como ripgrep(1) podem gerar saída no formato JSON, o que certamente torna tudo muito mais fácil, mas ainda estamos falando sobre processos de geração e análise de saídas.
Foi assim que nasceu a libag. Libag permite que você use o mecanismo de busca Ag (e suas instalações), mas da maneira certa (ou quase).
Libag pretende ser o mais simples possível e, portanto, divide o processo de pesquisa em três etapas simples:
Inicialize todas as estruturas internas do AG (via ag_init()
)
Faça quantas pesquisas quiser (via ag_search()
).
Limpe os recursos (via ag_finish()
).
As configurações de pesquisa personalizada são feitas por meio de ag_init_config()
e ag_set_config()
. Os resultados são uma lista de struct ag_result*, que contém o arquivo, uma lista de correspondências (contendo a correspondência e os deslocamentos do arquivo correspondentes à correspondência) e sinalizadores.
(Exemplos completos podem ser encontrados em exemplos/)
#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 pretende suportar todos os recursos (trabalho em andamento) do ag (ou pelo menos aqueles que fazem sentido para uma biblioteca). Além disso, permite controle detalhado sobre threads de trabalho, via ag_start_workers()
e ag_stop_workers()
(veja a documentação para mais detalhes).
Libag tem suporte (experimental) de ligações para outras linguagens de programação: Python e Node.js. Para obter mais informações e documentação mais detalhada, consulte ligações/python e ligações/javascript.
Libag requer as mesmas dependências do compilador ag: c99 e das bibliotecas: zlib, lzma e pcre. Essas bibliotecas podem ser instaladas uma por uma ou pelo seu gerenciador de pacotes.
Para distribuições do tipo Debian, algo como:
$ sudo apt install libpcre3-dev zlib1g-dev liblzma-dev
(ou siga as recomendações Ag aqui)
Assim que as dependências forem resolvidas, clone o repositório e construa. Libag suporta Makefile e CMake. Escolha o que melhor se adapta às suas necessidades:
$ 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
A documentação detalhada de cada rotina disponível pode ser encontrada nas páginas de manual. Além disso, o código-fonte é amplamente comentado (libag.h é uma leitura obrigatória!). Documentação sobre ligações e exemplos pode ser encontrada aqui.
Exemplos completos também estão disponíveis na pasta samples/ e são criados automaticamente junto com a biblioteca para sua conveniência ;-).
A Libag está sempre aberta à comunidade e disposta a aceitar contribuições, seja com problemas, documentação, testes, novos recursos, correções de bugs, erros de digitação, etc.
Libag é licenciado sob licença Apache v2.