Cómo grep en el código fuente sin captar comentarios

10

Busco una forma de grep en el código fuente sin tener a veces falsos positivos debido a los comentarios. Por ejemplo, si busco en foo en este código fuente .c:

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

Un ingenuo grepencontrará 3 casos en los que solo quiero uno. He visto esta forma de hacerlo en StackOverflow, pero no satisface mis necesidades: PHP no está disponible en la plataforma. También he encontrado esta manera para comentarios de una línea, pero solo resuelve una parte de mi problema.

Necesito usar herramientas de secuencias de comandos clásicas (awk, sed, bash, grep, etc.) y necesito que sea rápido incluso si hay miles de archivos.

¿Ahora si y cómo es posible grep en el código fuente, y solo el código fuente?

Coren
fuente
3
Construir una tabla de etiquetas podría ser un mejor enfoque, dependiendo de lo que esté haciendo.
Gilles 'SO- deja de ser malvado'

Respuestas:

10

Puede intentar un enfoque ingenuo para que coincida con no comentarios como este:

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

Esto sólo coincidirá con el prefijo inverso sobre comentarios - que es las líneas que comienzan con cualquiera //, /*, *o */- y por lo tanto no va a dejar de lado los bloques que se comentan a cabo con el /*y */par.


fuente
Modificado ligeramente para trabajar con comentarios sangrados: $ egrep -v "^ [[: space:]] * ((// | / * | *)" código fuente
mbonness
11

grep funciona en texto puro y no sabe nada sobre la sintaxis subyacente de su programa en C. Por lo tanto, para no buscar dentro de los comentarios tiene varias opciones:

  1. Elimine los comentarios C antes de la búsqueda, puede hacerlo usando gcc -fpreprocessed -dD -E yourfile.cPara obtener más información, consulte /programming/2394017/remove-comments-from-cc-code

  2. Escriba / use algunos scripts hacky de medio trabajo como ya ha encontrado (por ejemplo, funcionan saltando líneas que comienzan con //o /*) para manejar los detalles de todos los posibles comentarios de C / C ++ (nuevamente, vea el enlace anterior para algunos casos de prueba de miedo) . Entonces aún puede tener falsos positivos, pero no tiene que preprocesar nada.

  3. Use herramientas más avanzadas para hacer "búsqueda semántica" en el código. He encontrado "coccigrep": http://home.regit.org/software/coccigrep/ Este tipo de herramientas permite buscar algunas declaraciones de lenguaje específicas (es decir, una actualización de una estructura con un nombre de pila) y ciertamente dejan caer los comentarios.

dying_sphynx
fuente
1

Aquí hay una variación específica para todos los que llegamos tarde a esta pregunta:

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

Una lista si los archivos fuente C

ls -1 src/*.c

se canalizan a xargs, que ejecuta el preprocesador en un shell secundario

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

que posteriormente se canaliza a un comando grep deseado

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

que luego se canaliza a sed para prefijar cada línea con el nombre del archivo actual

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

Finalmente, todas las líneas en blanco repetidas se contraen en líneas simples usando cat:

cat -s

Esto funciona en un sistema RHEL6, pero supongo que es lo suficientemente general para otros sistemas * nix.

David A. Pimentel
fuente