Como grep no código fonte sem capturar comentários

10

Eu procuro uma maneira de grep no código fonte sem ter, às vezes, falso positivo por causa dos comentários. Por exemplo, se eu procurar em foo neste código-fonte .c:

/* 
 * foo has changed [...] and is now a 2-parameters function
 */
// foo(24)
foo(42, 28);

Um ingênuo grepencontrará 3 ocorrências em que eu quero apenas uma. Vi essa maneira de fazê-lo no StackOverflow, mas não preenche minhas necessidades: PHP não está disponível na plataforma. Também encontrei esse caminho para comentários de uma linha, mas isso resolve apenas uma parte do meu problema.

Preciso usar ferramentas de script clássicas (awk, sed, bash, grep etc.) e preciso que seja rápido, mesmo que haja milhares de arquivos.

Você agora se e como é possível grep no código fonte, e somente no código fonte?

Coren
fonte
3
Criar uma tabela de tags pode ser uma abordagem melhor, dependendo do que você está fazendo.
Gilles 'SO- stop be evil'

Respostas:

10

Você pode tentar uma abordagem ingênua para combinar não-comentários como este:

 $ egrep -v "^(//|/\*| \*)" sourcecode

Este jogo única inversa vai contra os comentários prefixados - que é linhas começando com um ou outro //, /*, *ou */- e, portanto, não vai deixar de fora blocos que são comentadas com o /*e */par.


fonte
Ligeiramente modificado ao trabalho para comentários recuados: $ egrep -v "^ [[: space:]] * ((// | / * | *)" código fonte
mbonness
11

O grep funciona em texto puro e não sabe nada sobre a sintaxe subjacente do seu programa C. Portanto, para não pesquisar nos comentários, você tem várias opções:

  1. Retire os comentários em C antes da pesquisa. Você pode fazer isso usando gcc -fpreprocessed -dD -E yourfile.cPara obter detalhes, consulte /programming/2394017/remove-comments-from-cc-code

  2. Escreva / use alguns scripts hackers que você já encontrou (por exemplo, eles funcionam ignorando as linhas que começam com //or /*) para lidar com os detalhes de todos os possíveis comentários em C / C ++ (novamente, veja o link anterior para alguns casos de teste assustadores) . Então você ainda pode ter falsos positivos, mas não precisa pré-processar nada.

  3. Use ferramentas mais avançadas para fazer "pesquisa semântica" no código. Eu encontrei "coccigrep": http://home.regit.org/software/coccigrep/ Esse tipo de ferramenta permite pesquisar algumas declarações de idioma específicas (por exemplo, uma atualização de uma estrutura com nome) e certamente eles descartam os comentários.

dying_sphynx
fonte
1

Aqui está uma variação específica para todos nós, que chegamos tarde a esta pergunta:

ls -1 src/*.c | xargs -i sh -c "echo;gcc -fpreprocessed -dD -E {} 2>&1 | grep -wi -e one -e two -e three -n | sed 's:^:{}\::'" | cat -s

Uma lista se os arquivos de origem C

ls -1 src/*.c

são canalizados para xargs, que executa o pré-processador em um shell filho

gcc -fpreprocessed -dD -E {} 2>&1

que é posteriormente canalizado para um comando grep desejado

grep -wi -e one -e two -e three -n

que é canalizado para sed para prefixar cada linha com o nome do arquivo atual

sed 's:^:{}\::'

Finalmente, todas as linhas em branco repetidas são recolhidas em linhas únicas usando cat:

cat -s

Isso funciona em um sistema RHEL6, mas presumo que seja geral o suficiente para outros sistemas * nix.

David A. Pimentel
fonte