Come grep sul codice sorgente senza catturare commenti


10

Cerco un modo per grep sul codice sorgente senza avere a volte falsi positivi a causa di commenti. Ad esempio, se cerco foo su questo codice sorgente .c:

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

Un ingenuo greptroverà 3 occorrenze dove ne voglio solo una. Ho visto questo modo di farlo su StackOverflow, ma non soddisfa le mie esigenze: PHP non è disponibile sulla piattaforma. Ho anche trovato questo modo per i commenti di una riga, ma risolve solo una parte del mio problema.

Ho bisogno di usare strumenti di scripting classici (awk, sed, bash, grep, ecc.) E ho bisogno che sia veloce anche se ci sono migliaia di file.

Ora se e come è possibile eseguire grep sul codice sorgente e solo sul codice sorgente?


3
Costruire una tabella di tag potrebbe essere un approccio migliore, a seconda di cosa stai facendo.
Gilles 'SO-smetti di essere malvagio'

Risposte:


10

Puoi provare un approccio ingenuo per abbinare i non commenti come questo:

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

Questo corrisponde solo inversa contro commenti prefissati - pari linee che inizia con //, /*, *o */- e quindi non lascio i blocchi che sono commentate con la /*e */coppia.


Modificato leggermente per funzionare con commenti rientrati: $ egrep -v "^ [[:: spazio:]] * ((// | / * | *)"
sourcecode

11

grep funziona su puro testo e non sa nulla della sintassi sottostante del tuo programma C. Pertanto, per non cercare nei commenti hai diverse opzioni:

  1. Rimuovi i commenti C prima della ricerca, puoi farlo usando gcc -fpreprocessed -dD -E yourfile.cPer i dettagli, vedi /programming/2394017/remove-comments-from-cc-code

  2. Scrivi / usa alcuni script mezzo funzionanti come hai già trovato (ad esempio funzionano saltando le righe che iniziano con //o /*) per gestire i dettagli di tutti i possibili commenti C / C ++ (di nuovo, vedi il link precedente per alcuni test spaventosi) . Quindi potresti avere ancora falsi positivi, ma non devi preelaborare nulla.

  3. Usa strumenti più avanzati per fare "ricerca semantica" nel codice. Ho trovato "coccigrep": http://home.regit.org/software/coccigrep/ Questo tipo di strumenti consente la ricerca di alcune dichiarazioni linguistiche specifiche (ovvero un aggiornamento di una struttura con un determinato nome) e certamente lasciano cadere i commenti.


1

Ecco una variazione specifica per tutti noi ritardatari di questa domanda:

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

Un elenco di file sorgente C.

ls -1 src/*.c

vengono reindirizzati a xargs, che esegue il preprocessore in una shell figlio

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

che viene successivamente reindirizzato nel comando grep desiderato

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

che viene quindi reindirizzato in sed per aggiungere il prefisso a ciascuna riga con il nome del file corrente

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

Infine, tutte le righe vuote ripetute vengono compresse in singole righe utilizzando cat:

cat -s

Funziona su un sistema RHEL6, ma suppongo che sia abbastanza generale per altri sistemi * nix.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.