segunda-feira, julho 07, 2008

Usando o Doxygen - Parte 2

Na parte 1 vimos o que é o Doxygen e porque usá-lo. Nesta segunda parte vamos ver como colocar no fonte as informações para ajudar o Doxygen a gerar a documentação.

As informações para o Doxygen precisam estar dentro de comentários especiais. As formas mais comuns de comentários para o Doxygen são /** comentário */ e /// comentário. O Doxygen aceita também /*! comentário */ e //! comentário. No caso dos comentários multilinha, um * no início do comentário é ignorado, levando ao popular formato
/**
* comentário
*/
Um comentário como o acima define uma descrição detalhada para o que vier em seguida. O Doxygen reconhece uma série de comandos dentro dos comentários. Estes comandos tem o formato @comando ou \comando. Um exemplo de comando é o \brief que permite definir uma descrição sucinta.

Um primeiro tipo de comentário útil é o \mainpage que define o texto a ser apresentado na página inicial da documentação:
/**
* \mainpage DukeMap
*
* \image html MiniTela.jpg
*
* \section intro_sec Introdução
*
* Este programa é um exemplo de uso das funções GDI
* do Windows, apresentando em uma janela um mapa do
* Duke Nuken 3D
*
* \section hist_sec Histórico
*
* Originalmente desenvolvido em 1996 e 1997 com o
* Borland C como uma aplicação Windows 3.1.
*
* Em 2004 foi transformado em um exemplo de uso da
* GDI para uma série de artigos postados na Sharepedia
* do MSDN Brasil.
*
* Adaptado em 2008 para mostrar o uso do Doxygen na
* documentação de programas.
*
*/
Neste exemplo estamos usando também os comandos \image, que coloca uma figura na documentação e \section que coloca um título em destaque:


Uma outra providência útil é identificar os nossos arquivos fonte:
/**
* \file DukeMap.c
* \brief Mostra um mapa de Duke Nuken 3D
* \author Daniel Quadros
* \version 1.20
* \date Criação: 07/nov/2004
* \date Alteração: 05/jul/2008
* \todo
* \li Pedir nome do arquivo
* \li Opção de zoom
*
* Este modulo contem o ponto de entrada do programa e
* a rotina de janela.
*/
Temos aqui vários comandos do Doxygen. Merece destaque o \todo que indica uma tarefa pendente, o Doxygen irá montar um índice de todos os \todo. Notar que temos dois comandos \date, o Doxygen não entra no mérito do conteúdo da maioria dos comandos se limitando a formatá-los e colocá-los na saída. Por último, temos os \li que indicam itens de uma lista. O resultado está abaixo:


Muitas a organização lógica do nosso programa não coincide com a organização física em arquivos. Por isso, é útil definir grupos:
/**
* \defgroup UI Interface com Operador
*
* Este grupo agrega as rotinas e estruturas de dados usadas
* para interface com o operador.
*
*/
O exemplo acima define um grupo chamado UI, cuja descrição sucinta é "Interface com o Operador".

Embora o Doxygen conheça a sintaxe e parte da semântica da linguagem, é sempre bom dar uma informação adicional nas declarações. Comecemos um define:
/**
* \def ARQ_MAPA
* \brief Nome do arquivo com o mapa a apresentar
*/
#define ARQ_MAPA "Bunker.map"
Vejamos agora um descrição de variável, informando o grupo a qual ela pertence:

/**
* \internal
* \var szAplic
* \ingroup UI
* \brief Nome da Aplicação
*/
char szAplic [] = "DukeMap";
Muitas vezes queremos gerar duas versões da documentação, uma contendo somente as interfaces externas dos módulos e outra contendo os detalhes internos. Podemos fazer isto marcando os itens internos com \internal como acima.

Outros tipos de comando para informar o que estamos comentando são \typedef e \struct:
/**
* \internal
* \typedef STAT
* \ingroup Mapa
* \brief Características de teto e chão
*
* Uso dos bits de ceilingstat e floorstat
*/
typedef enum
{
STAT_PARALLAXING = 0x01, /**< 1 = Parallaxing, 0 = not */
STAT_SLOPED = 0x02, /**< 1 = sloped, 0 = not */
STAT_SWAP_XY = 0x04, /**< 1 = swap, 0 = not */
STAT_DOUB_SMOOSH = 0x08, /**< 1 = double smoshiness */
STAT_X_FLIP = 0x10, /**< 1 = x-flip */
STAT_Y_FLIP = 0x20, /**< 1 = y-flip */
STAT_ALIGN = 0x40 /**< 1 = align texture to first wall */
} STAT;

/**
* \internal
* \struct DSC_WALL
* \ingroup Mapa
* \brief Descritor de parede
*
* Esta estrutura descreve uma parede do mapa, para fins
* de desenho na tela.
*/
typedef struct
{
int x, /**< coordenada do ponto esquerdo */
y; /**< coordenada do ponto esquerdo */
short nextwall; /**< indice da próxima parede */
} DSC_WALL;
Notar no exemplo acima o uso de /**<; descrição */ para colocar uma descrição depois do item sendo descrito. Isto é util para documentar não somente enums e structs, mas também variáveis que não requeiram uma descrição mais sofisticada.

Na descrição de rotinas podemos documentar os parâmetros e o retorno:
/************************************************************************/
/**
* \brief Le o mapa
* \ingroup Mapa
* \param szMapa nome do arquivo com o mapa
* \return TRUE se sucesso, FALSE se falha
*/
/************************************************************************/
BOOL LeMapa (char *szMapa)
{
...
}
Note que na descrição dos parâmetros precisamos usar o mesmo nome que o usado no código.

Com isto cobrimos os comandos básicos. O manual do Doxygen possui a relação completa.

Na terceira e última parte vamos ver passo a passo como gerar um arquivo CHM usando o Doxygen e o Microsoft Help Workshop.

4 comentários:

Presidente disse...

Parabéns pelo post, estou começando a implementar essa facilidade de documentar os códigos e seu texto esta sendo uma mão na roda.

Abraços

Anônimo disse...

Parabéns pelo post.
Estou num projecto que está a crescer e isto veio mesmo a calhar. :)

Tiago Faria Bicalho disse...

Muito bom mesmo.. procurei isso pela net o local que melhor explicou foi aki..
meus parabens

Ricardo disse...

Olá, instalei o .exe do Doxygen, tenho um projeto em C++ com arquivos .cpp e seus headers .h. Eu adiciono os comentários como descrito no post incluindo od comandos, porém quando gero o html com o Doxygen GUI wizard ele só me mostra os arquivos e includes e nada mais. Existe alguma configuraçao específica que devo fazer?