"El reto de la semana", 3ª edición

Éste es fácil. Se premiara la claridad y elegancia del código. Pero que quede claro que la programación no es arte Smiling

Hacer un programa que cuente las funciones (no prototipos) que hay en un fichero C. Debe imprimir el resultado por salida estándar. Puedes utilizar cualquier lenguaje. No se veta el uso de NINGUNA característica de ningún lenguaje.

[EDITADO]

Lo voy a enunciar de otra manera para que quede más claro:

Dado un fichero cualquiera escrito en ANSI C, devolver el número de definiciones de función que contenga. No se deben contar las funciones que pudieran aparecer en los ficheros incluidos por el preprocesador, dado que técnicamente no están en el fichero .c. Además, la existencia del fichero de partida no implica en absoluto que se disponga también de otros módulos o dependencias que pudiera implicar su compilación.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de magmax

Solución Python

facilísimo (quizá un poco enrevesado):

#!/usr/bin/python

import re, sys

rawstr = r"""[A-Za-z_][A-Za-z_\-]*[ \r\n*]+([A-Za-z_][A-Za-z_\-]*)[\n\r ]*\([A-Za-z_\- \r\n*,]*\)[\r\n ]*\{"""

if len(sys.argv) < 2:
    print "Introduzca el nombre del archivo"
    sys.exit(-1)

fd = open (sys.argv[1])
sol = re.findall(rawstr, fd.read())
fd.close()

print "Encontradas %d funciones: %s"%(len(sol), sol)

Se puede ajustar más la expresión regular y... arreglado.

Miguel Ángel García
http://magmax.org

Imagen de magmax

problema con las expresiones regulares

Independientemente de si el programa anterior obtiene todas las funciones deseadas o no, me he encontrado con un problema que, seguro, no resuelve: ¿cómo detectar cuándo una función está comentada de una forma sencilla?

Se admiten sugerencias, ya que lo que se me ocurre a mí pasa siempre por un analizador sintáctico...

Miguel Ángel García
http://magmax.org

Imagen de magmax

Una posible solución.

Bueno... Viendo lo que hace la gente, se me ha ocurrido otra manera. No cumple los requisitos, pero creo que es interesante:

$ gcc -pg ficherito.c -o ficherito; ./ficherito; gproc ficherito

Al final del todo te pone "Index by function name", miras el último numerito de índice y lo tienes.

Además, consigo una lista de las funciones definidas y demás.

Esta solución NO es válida para todas las premisas. Para empezar, porque no funciona para un fichero ANSI C, sino para un programa completo. Tampoco obtiene un número, sino todas las estadísticas de uso y tiempos empleados. Sin embargo, me parecía interesante comentarla en un lugar para "frikis" como éste Eye-wink por si alguien la desconociera.

Miguel Ángel García
http://magmax.org

Imagen de david.villa

Esto es interesante para el

Esto es interesante para el manual de "depuración avanzada" que tengo a medias desde hace milenios.

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

Imagen de magmax

lo sé

lo sé. Por eso la puse.

Miguel Ángel García
http://magmax.org

Imagen de magmax

La solución más sencilla...

... pasa por que te lo solucionen otros Laughing out loud

$ pmccabe ficherito.c

o, mejor:

$ pmccabe ficherito.c|wc -l

Si no te funcionan, prueba con esto:

# apt-get install pmccabe

;-D

Miguel Ángel García
http://magmax.org

Imagen de david.villa

Tiene más interés si la

Tiene más interés si la solución propuesta la has hecho tú, no crees? Los retos anteriores también estaban resueltos de antemano. Sticking out tongue

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

Imagen de int-0

Solución en bash (en un comando)...

Requisitios: el archivo ha de ser compilable (no es necesario que se pueda enlazar).

Supongamos que se llama "hola.c", pues fácil:

$ gcc -c hola.c && objdump -t hola.o | awk '/g/ {print $2}'| wc -l

Ale ya...

P.D. Courtessy of Cleto and me...
------------------------------------
init=/bin/bash to conquer the world!

------------------------------------------------------------
$ python -c "print 'VG9udG8gZWwgcXVlIGxvIGxlYSA6KQ==\n'.decode('base64')"
------------------------------------------------------------

Imagen de david.villa

Muy original, pero compilar

Muy original, pero compilar el .c puede que no siempre sea tan fácil. Imagina que tiene muchos includes, de librerías que ni siquiera tienes. También puede pasar que esos includes tengan a su vez definiciones de funciones (algo horroroso pero que puede pasar) y esas funciones no queremos contarlas.

Conste que yo no tengo ninguna solución pensada que pudiera influirme a la hora de juzgar las vuestras.

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

Imagen de int-0

Tranki...

Mmmm... nosotros lo probamos, al pasar -c al gcc sólo compila el archivo que le das, ninguno más... vamos que pasa de los includes ya que no llega al linkado, así tendremos la tabla de exportación de las funciones que nos interesa en el .o que se compila...

Corrigeme si me equivoco... ¿es en el linkado donde SI deben encontrarse todas librerias que use tu código? por tanto si úncamente compilamos... no se buscarán... ¿no? de esta forma nos ahorramos el disponer de esas librerias que puede que no tengamos y contar sus propias funciones... al menos nuestras pruebas al respecto fueron satisfactorias... Smiling

------------------------------------
init=/bin/bash to conquer the world!

------------------------------------------------------------
$ python -c "print 'VG9udG8gZWwgcXVlIGxvIGxlYSA6KQ==\n'.decode('base64')"
------------------------------------------------------------

Imagen de int-0

Pues si...

Parece que el requisito para que esta fórmula funcione es contar con todas las cabeceras que use tu código... te todas formas eso tampoco parece descabellado... Sticking out tongue
------------------------------------
init=/bin/bash to conquer the world!

------------------------------------------------------------
$ python -c "print 'VG9udG8gZWwgcXVlIGxvIGxlYSA6KQ==\n'.decode('base64')"
------------------------------------------------------------