Anuncios Google

Documentando el código con Doxygen

Tutoriales de Programaciones

Este es el primero de una, posiblemente, serie de tutoriales sobre aspectos no relacionados directamente con la programación, como son la documentación, organización y arquitectura, UML e ingeniería del software en general, ya que no he visto nada por el estilo en scenebeta. Este en concreto es sobre la documentación mediante el uso de Doxygen. Si sabes programar, o estás aprendiendo y ya sabes lo básico, continua leyendo.

Introducción:

Uno de los grandes problemas a los que se enfrenta un programador cuando lee un código ajeno es que la dificultad de comprensión es directamente proporcional al tamaño de éste. Entender cómo está organizado el código es tedioso aunque esté bien comentado, ya que tendremos que navegar a la deriva entre miles y miles de lineas de código. Incluso cuando el proyecto no es un programa sino una biblioteca que queremos usar, tenemos que pasar largas y tediosas horas leyendo código e intentando entender el porqué de cada archivo de cabecera, de cada archivo fuente, de cada función... cuando en realidad no queremos saber como está implementado sino como usar la biblioteca. Sin duda una buena documentación es necesaria, incluso imprescindible, pero crear un documento puede resultar aburrido y quitarnos mucho tiempo. ¿Cual es la solución? Sin duda, Doxygen.

Doxygen es un programa que analiza el código en busca de directivas en forma de comentarios y las transforma en documentación, bien HTML, bien LaTeX e incluso podemos crear una página de manual de linux para visualizar con el mítico comando "man". Doxygen acepta multitud de lenguajes como C/C++ o Java. La principal ventaja de Doxygen es sin duda que las directivas no son más que comentarios de forma que no tenemos que crear una documentación aparte, sino, simplemente, comentar el código.

Sin más comenzamos con un ejemplo sencillo. Supongamos la siguiente cabecera de función:

/**
 * @brief Multiplica 2 matrices 3x3 y devuelve el resultado
 * @param A La primera matriz a multiplicar de tamaño 3x3
 * @param B La segunda matriz a multiplicar de tamaño 3x3
 * @return Una nueva matriz C = AxB.
 */
float ** multiplicaMatrices (float **A, float **B);

Sin tener ni idea de doxygen, ya podeos intuir lo que quieren decir los comentarios. Gracias a estos comentarios (y la documentación generada posteriormente a partir de estos) podemos saber que esta función multiplica matrices 3x3 sin tener que conocer la implementación.

Lo primero que vemos es que el bloque de comentario es casi normal salvo porque el comienzo tiene dos asteriscos en lugar de 1:

// Lo siguiente es un comentario normal
/*
  ...TEXTO...
 */
 
// Comentario Doxygen (dos asteriscos**)
// + un asterisco al comienzo de cada linea interna (opcional)
/**
 * ...TEXTO...
 */

A este tipo de comentario le llamaremos bloque Doxygen. Esta no es la única forma de definir los bloques Doxygen (aunque a un servidor es la que más le gusta y probablemente es también la más usada). Hay en total 4 estilos:

// 1.- Estilo JavaDoc (el anterior)
/**
 * ...TEXTO...
 */
 
// 2.- Estilo Qt
/*!
 * ...TEXTO...
 */
 
 
 
// 3.- Usando varias lineas consecutivas para formar un bloque, cada una con 3 barras o 2 barras+exclamación:
 
///
/// ...TEXTO...
///
 
// o
 
//!
//! ...TEXTO...
//!
 
// 4.- Delimitando los bloques con muchos asteriscos:
 
/********************************************//**
 * ...TEXTO...
 ***********************************************/
 
// Notar que la primera parte de la primera linea no forma parte del bloque.
// El bloque realmente comienza con el /** posterior.
// Si no comienza exáctamente con /** no es un bloque doxygen:
 
/*********************************
 * ESTO NO ES UN BLOQUE DOXYGEN
 *********************************/
 

Realmente son 2 estilos: JavaDoc y Qt. Los otros dos no son estilos propiamente dichos: el cuarto es el primero utilizando más asteriscos por cuestiones estéticas y el tercero es simplemente un conjunto de lineas seguidas que se toman como bloque (una linea de comentario doxygen es cualquiera que comience por /// o por //!).

/// Esto es una linea doxygen
 
//! Esto también es una línea doxygen
 
///
/// Esto es un bloque ya que tiene 2 o más lineas

Como recomendación personal podeis utilizar el primero, JavaDoc, ya que es el que, personalmente, he visto en más ocasiones y me parece más estético. Sin embargo el uso de uno u otro es cuestión de gustos.

Directivas básicas:

Al igual que pasaba con los bloques de comentarios, para las directivas hay 2 estilos: \ y @:

/**
 * @brief Esta es una forma de indicar la directiva
 * \note Y esta es la otra
 */

Cual usar dependerá unicamente de vuestros gustos. Las directivas más comunes son:

  • brief: Indica que lo que sigue a continuación es el resumen de la función/clase/estrucura/enumerado/etc documentado.
  • param: Parámetro de una función. Debe estar seguido del nombre de la variable a la que nos referimos. Por ejemplo: @param a
  • return: Lo que devuelve la función
  • note: Una anotacion.
  • see: Referencia a una función.

Hay que decir que la primera linea siempre se tomará como un brief si usamos el estilo JavaDoc. Cualquier linea que no comience con una directiva se supone que forma parte de la descripción extendida (siempre y cuando haya una linea en medio):

/**
 * @brief Descripción resumida
 * Aqui sigue siendo un resumen
 *
 * Esto ya es la descripción detallada
 */

No tenemos que definir los comentarios justo antes de la declaración, podemos ponerlos justo después mediante comentarios en linea que comienzan por '<'. Si el comentario es una única linea indica una descripción resumida:

int a; ///< Descripción resumida de a
char b; //!< Descripción resumida de b

Los comentarios en bloque indican descripción extendida:

float c; /*!< Descripción extendida de c*/
bool d; /**< Descripción extendida de d*/
double d; ///< Descripción extendida de d
                ///< Recordar que esto es un bloque!

Incluso podemos documentar algo en otra parte del código indicando a qué hace referencia con las directivas:

  • struct para documentar una estructura
  • union para documentar una union
  • enum para documentar un enumerado
  • fn para documentar una función
  • var para documentar una variable, typedef o enum
  • def para documentar un #define
  • typedef para documentar un typedef
  • file para documentar un archivo
  • namespace para documentar un namespace
  • class para documentar una clase c++ o Java
  • package para documentar un paquete Java
  • interface para documentar una interfaz

Ejemplo:

/**
 * @class miClase
 * @brief Representa una clase vacía
 */
 
/**
 * @struct miEstructura
 * @brief Representa una estructura vacia
 */
 
// Antes o después de los comentarios o incluso en otro fichero...
 
class miClase{
  ...
};
 
struct miStruct{
  ...
};

Extras:

Doxygen permite insertar código de otras herramientas, como por ejemplo "dot", que permite crear diagramas especificando su aspecto mediante texto. No vamos a entrar en detalle en este tema, aunque si a alguien le interesase podría hacer otro tutorial dedicado a dot. Por ahora mirad el archivo mainPage.h del comprimido "tutorialDoxygen.zip" para ver el aspecto que tienen las directivas dot y el HTML para ver el resultado.

Generando la documentación:

Una vez comentado nuestro código procedemos a ejecutar Doxygen para que genere automáticamente nuestra documentación. A este programa lo único que tenemos que indicarle es un archivo de configuración, el cual podemos generar mediante el comando

$ doxygen -g 

Lo cual nos creará el archivo "Doxyfile". Pasamos a modificarlo. No tendremos problemas a la hora de entender las opciones ya que hay multitud de comentarios. Por ejemplo, cambiaremos:

  • linea 28: El nombre del proyecto (Por ejemplo PROJECT_NAME = "Proyecto de prueba")
  • linea 34: La versión (PROJECT_NUMBER = 0.1.2)
  • linea 41: Directorio de salida (OUTPUT_DIRECTORY = ./doc)
  • linea 63: El idioma (OUTPUT_LANGUAGE = Spanish)
  • linea 584: Los ficheros de entrada (INPUT = ./include/cabecera.h ./src/main.cpp clase.java)
  • linea 700: Si queremos poder navegar por el código (SOURCE_BROWSER = YES)
  • linea 777: Si queremos generar la documentación HTML (GENERATE_HTML = YES por defecto)
  • linea 1088: Si queremos generar la documentación LaTeX (GENERATE_LATEX = YES por defecto)
  • linea 1216: Si queremos generar la documentación MAN (GENERATE_MAN = YES)
  • linea 1245: Si queremos generar la documentación XML (GENERATE_XML = YES)

Podemos tardar un buen rato en configurar la documentación a nuestro gusto. Una vez que ya lo tenemos simplemente ejecutamos

$ doxygen

Lo que nos creará la documentación en el formato especificado. Si hemos indicado que genere documentación HTML (por defecto) generará, entre otros, un archivo index.html en la carpeta HTML que podremos abrir con un navegador. Como ya habíamos comentado, también es posible generar documentación en LaTeX y man entre muchos otros.

Ejemplo:

En el archivo de ejemplo podéis ver un ejemplo extremadamente tonto de uso de doxygen. Simplemente son unas cuantas funciones y clases vacías con comentarios doxygen junto con su correspondiente documentación HTML ya generada. Mirad los archivos .h y .c para ver los comentarios y el archivo html/index.html para ver el resultado.

También he subido un ejemplo real, una biblioteca hecha por mi mismo con decenas de clases, cientos de funciones, enumerados, estructuras, etc. Es una biblioteca de gráficos 2D con aceleración hardware, mediante OpenGL y SDL (de ahí el nombre YASOL: Yen Another SDL-OpenGL Library). Solo he subido la documentación ya que el código en si para el caso no interesa. Podéis ver el resultado en los cientos de páginas HTML que genera Doxygen por las cuales podéis navegar e incluso usar un buscador integrado.

Conclusiones:

Saber programar no es el final del camino. Una vez que sabemos programar hay que empezar a hacer programas de calidad, siguiendo buenos hábitos de programación, comentando el código, y teniendo una buena organización, dividiendo el programa en varios ficheros, funciones, clases, estructuras, etc. Los comentarios no deben hacerse a posteriori, una vez ya hecho el programa, sino a la vez que se va escribiendo. Igualmente podemos ir documentando el porqué de cada clase/estructura/función relevante de forma que otra persona pueda saber qué representa. Incluso si no tienes previsto que nadie lea tu código, no está de más documentar el código para que en un futuro puedas leerla si no recuerdas como hiciste las cosas.

Por último decir que comentar el código con sintaxis doxygen no solo sirve para generar la documentación. Algunos IDEs como Netbeans analizan los comentarios Doxygen para mostrar al usuario una ayuda contextual con la definición que hayamos escrito de cada función, clase, etc. Aun si no pensamos generar la documentación ni usamos un IDE compatible con Doxygen, no nos cuesta nada escribir los comentarios con esta sintaxis por lo que pueda pasar en un futuro. Asi que, ya que tenemos que escribir los comentarios, ¿por que no comentar con la sintaxis de Doxygen?.

Descargar EjemploTutorialDoxygen (Sólo usuarios registrados).

Descargar DocLibYasol (Sólo usuarios registrados).

4.076925
Tu voto: Ninguno Votos totales: 4.1 (39 votos)

Anuncios Google

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 jorejah

Me recuerdas a ...

...

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.