2010-07-31 14 views
6

Tengo algunos archivos fuente en C que se están expandiendo lentamente. Tiendo a mantener los prototipos con documentación en el archivo .h en buen estado, agrupados en funciones y tipos relevantes con #pragma mark. El código está escrito y documentado de una manera que requiere leer el archivo .h junto con el archivo .c. Me gustaría que los archivos se ordenen de una manera que lo facilite.¿Hay alguna herramienta para mantener ordenados mis archivos fuente en C?

¿Hay alguna manera de mantener las declaraciones de funciones en el archivo .c en el mismo orden que sus prototipos en el archivo .h? Estoy buscando una herramienta para leer el archivo .h (con #pragma mark s si es posible) y reordenar el archivo .c correspondientemente.

¿Posible?

+0

¿Qué debería hacer esta herramienta con los elementos en el archivo '.c' que no tienen un elemento correspondiente en el archivo' .h'? Por ejemplo, las funciones estáticas pueden estar relacionadas con funciones globales y ubicarse antes o después de ellas. – jilles

+0

Eso no está en la lista de requisitos. Si existe una herramienta que satisfaga los requisitos anteriores, estoy seguro de que podría manejar este caso. – Joe

Respuesta

1

He hecho la trituración de código antes. Lo más cercano que podrías conseguir es escribir uno (hasta donde yo sé). Con una API de análisis estático, puede analizar el código fuente y luego, basándose en el código de cada archivo de encabezado, organizar todos los archivos en un archivo .c correspondiente.

Una compañía llamada SciTools envía un analizador de código fuente llamado 'entender 4 C++' que tiene una API C que hace que esto sea bastante fácil. Pero probablemente debas escribir la herramienta tú mismo. Tal como están las cosas, escribí una API administrada que se encuentra sobre su C API. Mi gestión se encuentra en codeplex aquí: http://understandapi.codeplex.com/

Así es como estructuraría el programa.

  1. Primero tiene que crear una base de datos de todo su código fuente. Puede hacerlo utilizando un script por lotes, si lo desea, o un script de PowerShell, o puede hacerlo usted mismo manualmente. Por lo general, es tan simple como señalar un directorio y, en efecto, decir 'crear una base de datos con todos los archivos'. Puede determinar si desea archivos * .c, * .h o * .cpp en su base de datos.

  2. Luego, usando la API puede navegar por todos los archivos con la extensión .h.

  3. Para cada archivo de encabezado, verifica que haya un archivo .c correspondiente. Esto se hace tomando una cadena del nombre del archivo, reemplazando la extensión del archivo (.NET lo hace fácil) y verificando si el archivo existe. Si existe, continúe con el próximo paso.

  4. Luego el programa debe iterar a través de todas las entidades definidas en el archivo .h.

  5. Para cada entidad, luego encuentra una referencia a su definición (no declaración), y ve si existe en el archivo correspondiente .c. Si está allí, encuentra los números de línea de la definición del código, abre el archivo para leer y lee las líneas de código necesarias (y también los comentarios) y las escribe en un archivo temporal.

  6. Cuando haya terminado, sobrescriba el archivo .c con el archivo temporal.

  7. Proceda con el resto de los archivos en la base de datos.

Ahora no es tan fácil. Puede tener problemas en el camino en la forma de: 1. Código compilado condicionalmente, en cuyo caso será más difícil de analizar, aunque es posible.Entender 4 C++ analiza las directivas de compilación condicional y diferencia entre el código activo y el inactivo. Pero solo manejar esto lo haría realmente difícil. 2. Espacios de nombres: esto complicaría las cosas.

Sin embargo, si solo está interesado en organizar el código entre ciertas directivas #pragma, podría simplificar las cosas nuevamente.

Avísame si te interesa más, y tenemos una charla fuera de línea.

+0

Gracias por su respuesta. Estoy trabajando con C, no con C++, así que solo estamos hablando de funciones, typedefs, structs, enumeraciones, etc. Creo que si escribiera mi propia herramienta (puedo hacerlo) sería bastante simple, y seguiría los mismos tipos de pasos (menos las complicaciones de C++). Escribo con un estilo coherente, por lo que escribir Python para cortar cosas y volver a unirlas como cadenas (¡no AST!) No sería difícil. – Joe

+0

Bueno, veamos, esta herramienta también C. También hace ADA, Java, C#, Fortran y algunos más, además, creo. También se ejecuta en una gran cantidad de sistemas operativos. –

1
  • Utilice un buen IDE ... No será necesario mantener el orden en el archivo de cabecera/archivo c alineado.

  • Si todavía no le sirve ... Guarde todas las declaraciones y definiciones en orden alfabético. Cuando agrega una nueva función, sabe dónde insertar la nueva función .

    P.S. Creo en el http://www.dmoz.org/ diciendo ::

    Humans Do it better 
    
+0

Los humanos podrían hacerlo mejor (debatible), pero son más lentos y mucho más caros. – Christo

+0

¿Por 'uso de un IDE bueno' quiere decir uno que permite saltarse el código fuente? Estoy escribiendo en Xcode, que está bien, pero quiero que el código sea legible en un editor de texto en cualquier plataforma. Preferiría llevar el trabajo al final de la producción para facilitar la vida del lector, no decir 'usar un buen IDE'. – Joe

+0

Y con respecto a su segundo punto, estoy colocando las funciones en un orden determinado, por ejemplo construcción/destrucción de ADT, persistencia, operaciones en ADT, etc. Imponer un esquema de ordenamiento artificial, como por orden alfabético, no es ideal. – Joe

1

dudo encontrará una herramienta como esta fuera de la plataforma. Entonces, necesitarías una herramienta personalizada. No desea intentar hacer esto con algún método de hacking de cadenas (por ejemplo, Perl) porque los detalles de precisión de analizando C y C++ son mucho más allá de lo que puede hacer de esta manera. Si no te importa hackeo de cuerdas dañar sus archivos a veces, tal vez puede salirse con la suya.

Mi empresa es DMS Software Reengineering Toolkit podría utilizarse para hacer esto de forma fiable una advertencia.

DMS es un motor genérico para analizar, analizar y transformar el código fuente mediante la tecnología del compilador parametrizada por definiciones de lenguaje explícitas. DMS tiene definiciones de lenguaje robustas para muchos idiomas, incluyendo C y C++ en variedad de dialectos. Con los frontales DMS C o C++, puede analizar el código fuente , compilar estructuras de datos de compilador llamadas AST, realizar análisis sobre el código, transformar los AST, y luego regenerar el código compilable, incluidos los comentarios y todas las directivas de preprocesador.

La advertencia tiene que ver con el código fuente de análisis que contiene las directivas del preprocesador: tienen que estar bien estructuradas [por ej. #ifdef #endif necesita anidarse alrededor de otras instrucciones como el normal, etc., en lugar de usarse en un límite de declaración. Esto sucede algo en el código C; mucho menos en código C++. Nuestra experiencia es que si está dispuesto a modificar su código C poco, puede hacer que este problema en particular desaparezca.

Para su tarea específica, que lo hacen más o menos como la respuesta para Toolworks científicos descritos:

  1. Elija una unidad de compilación, y analizarlo usando DMS. Debe proporcionar la misma información que proporciona el compilador, para que pueda localizar los archivos de encabezado, etc.
  2. DMS produce un AST tanto para su unidad de compilación como para todos los archivos de encabezado.
  3. Recorre los AST para extraer el orden de las declaraciones en los encabezados y la unidad de compilación.
  4. Restructure el árbol unidad de compilación de acuerdo con el orden derivado de 3)
  5. embellecida la unidad de compilación resultante AST

[A razón de hacer esto con DMS en lugar de Toolworks científica es que DMS está diseñado para parse/transform/regenerate code, mientras que SciTool en mi humilde opinión realmente solo está diseñado para analizar y analizar. DMS proporciona acceso a los detalles precisos necesarios para la transformación que SciTools no hace, al menos no la última vez que miré].

Se producirán complicaciones debido a condicionales, macros, espacios de nombres, ... pero tendrá que decidir la política para la resolución. Por ejemplo, si un archivo de encabezado tiene un #if ... #else .... #endif, y las declaraciones en la cláusula then tienen un orden diferente del que tienen en la cláusula else, ¿cuál es el orden deseado? ¿Qué pasa si una definición de función es creada por una macro en el encabezado? Pero, todo esto es lo que hace que construya una herramienta real, er, diversión.

Mi opinión personal es que esto parece mucho trabajo para el efecto que está obteniendo. Si hace todo esto, ¿cuánto mejor será su proceso de ingeniería de software? Normalmente usamos DMS para verificar si hay errores de codificación o cambiar el código de manera que las personas no pueden (por ejemplo, insertar instrumentación de tiempo de ejecución temporalmente o consejos tipo AOP), donde está claro que un motor mecánico tiene rentabilidad.

+1

Me encantaría tener en mis manos este DMS en algún momento. Me he familiarizado íntimamente con la API de SCI, pero siempre estoy buscando formas de ampliar mi comprensión de estas cosas. –

Cuestiones relacionadas