Jak grepować na kod źródłowy bez łapania komentarzy

10

Poszukuję sposobu na grep w kodzie źródłowym bez czasami fałszywie dodatnich z powodu komentarzy. Na przykład, jeśli szukam foo na tym kodzie źródłowym .c:

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

Naiwny grepznajdzie 3 przypadki, w których chcę tylko jedno. Widziałem ten sposób na StackOverflow, ale nie spełnia moich potrzeb: PHP nie jest dostępne na platformie. Znalazłem również tę drogę dla komentarzy w jednym wierszu, ale to rozwiązuje tylko część mojego problemu.

Muszę używać klasycznych narzędzi skryptowych (awk, sed, bash, grep itp.) I muszę być szybki, nawet jeśli istnieją tysiące plików.

Czy wiesz, czy i jak można grepować na kod źródłowy i tylko kod źródłowy?

Coren
źródło
3
Tworzenie tabeli tagów może być lepszym podejściem, w zależności od tego, co robisz.
Gilles „SO- przestań być zły”

Odpowiedzi:

10

Możesz wypróbować naiwne podejście, aby dopasować nie-komentarze w następujący sposób:

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

Będzie to tylko odwrotny meczu z prefiksem komentarze - czyli linie zaczynające się też //, /*, *lub */- a więc nie zostawimy na bloki, które są komentarzem z /*i */pary.


źródło
Zmodyfikowano nieznacznie, aby działał z wciętymi komentarzami: $ egrep -v "^ [[: space:]] * ((// | / * | *)"
sourcecode
11

grep działa na czystym tekście i nie wie nic o podstawowej składni twojego programu C. Dlatego, aby nie przeszukiwać komentarzy, masz kilka opcji:

  1. Usuń C-komentarze przed wyszukiwaniem, możesz to zrobić za pomocą gcc -fpreprocessed -dD -E yourfile.cAby uzyskać szczegółowe informacje, zobacz /programming/2394017/remove-comments-from-cc-code

  2. Napisz / użyj skryptu na wpół działającego skryptu, takiego jak już znalazłeś (np. Działają one pomijając linie zaczynające się od //lub /*), aby obsłużyć szczegóły wszystkich możliwych komentarzy C / C ++ (ponownie, patrz poprzednie łącze dla niektórych przerażających przypadków testowych) . Wtedy nadal możesz mieć fałszywie pozytywne wyniki, ale nie musisz niczego przetwarzać.

  3. Użyj bardziej zaawansowanych narzędzi do wykonywania „wyszukiwania semantycznego” w kodzie. Znalazłem „coccigrep”: http://home.regit.org/software/coccigrep/ Tego rodzaju narzędzia pozwalają na wyszukiwanie określonych instrukcji językowych (tj. Aktualizację struktury o podanej nazwie) i na pewno usuwają komentarze.

dying_sphynx
źródło
1

Oto konkretna odmiana dla nas wszystkich spóźniających się na to pytanie:

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

Lista, jeśli pliki źródłowe w C.

ls -1 src/*.c

są przesyłane strumieniowo do xargs, który wykonuje preprocesor w powłoce potomnej

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

który jest następnie przesyłany do żądanego polecenia grep

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

który jest następnie przesyłany do sed w celu poprzedzenia każdego wiersza bieżącą nazwą pliku

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

Na koniec wszystkie powtarzające się puste linie są zwijane do pojedynczych linii za pomocą cat:

cat -s

Działa to na systemie RHEL6, ale zakładam, że jest wystarczający dla innych systemów * nix.

David A. Pimentel
źródło