Cuando se crea codigo fuente, una buena practica es documentarlo y si esta documentacion basica se puede utilizar para generar un manual de referencia del codigo en HTML, PDF, PS, o XML a partir de los fuentes con unos cuantos comandos de texto en menos de un minuto, pues que mejor. Existen varias herramientas para ello, una de ellas es DOXYGEN para codigos de java, fortran, C y C++. Para instalar esta herramienta usar: # aptitude install doxygen graphviz una vez instalada, hay que generar el archivo de configuracion de DOXYGEN, para ello usar: $ doxygen -g de aqui podemos editar archivo Doxyfile generado segun las necesidades de la documentacion a generar, un ejemplo de ella para generar la salida en html, latex y XML se pone en el archivo Doxyfile en esta pagina. Para generar la documentacion de los fuentes en la carpeta donde este el archivo de configuracion y los archivos fuentes, usar: $ doxygen La documentacion generada con DOXYGEN se mostrara en carpetas separadas para cada una de las salidas seleccionadas por ejemplo: html, latex, xml, etc. Para ver la documentacion generada para html, usar en ambiente texto por ejemplo $ cd html $ chrome index.html Pa generar la documentacion en formato PDF a partir de la salida de latex usar $ cd latex $ make pdf $ xpdf refman.pdf en este caso se supone que se tiene instalado latex en la maquina, en caso contrario instalarlo usando: # aptitude install science-typesetting texlive-science y adicionalmete si se quiere: # aptitude install texmaker texmacs texmacs-extra-fonts texlive-latex-base texlive-latex-recommended myspell-en-us myspell-es Hay varios estilos de documentacion, aqui pongo una que se me hace facil de usar para codigos en C++. #ifndef __test__ #define __test__ /// Descripcion breve de la clase. /** * Descripcion detallada de la clase ... * * @author Antonio Carrillo * @date Winter 2010 * @version 0.0.1 * @bug No errors detected * @warning No warnings detected * @todo Exception handling */ class test { private: /// Descripcion breve. const char *nmClass; /** * Descripcion corta. * * Descripcion larga ... * * 0 = Dirichlet, 1 = Neumann (or Robin) */ int bdType; public: /** * Descipcion breve. * * Descripcion detallada ... * * Algo de latex ... * * \f[ * |I_2|=\left| \int_{0}^T \psi(t) * \left\{ * u(a,t)- * \int_{\gamma(t)}^a * \frac{d\theta}{k(\theta,t)} * \int_{a}^\theta c(\xi)u_t(\xi,t)\,d\xi * \right\} dt * \right| * \f] * * * @param[out] clas Descripcion del parametro de salida * @param[in] fun Descripcion del parametro de entrada */ test(const char *clas, const char *fun) { nameClassFunct(clas, fun); } /** * Descripcion breve. * * Descripcion detallada * * @param nVert Descricion del parametro * @param[in] g Descricion del parametro * @param[in] me Descricion del parametro * @param[out] values Descricion del parametro * @param z Descricion del parametro * @return Descripcion de lo que regresa */ int eval(int nVert, double **g, StdElem *me, double ***values, double *z); }; /** * Descripcion breve de la clase. * * Descripcion detallada de la clase * * Otro parrafo de la descripcion ... * * Algo de formulas con latex * * \f{eqnarray*}{ * g &=& \frac{Gm_2}{r^2} \\ * &=& \frac{(6.673 \times 10^{-11}\,\mbox{m}^3\,\mbox{kg}^{-1}\, * \mbox{s}^{-2})(5.9736 \times 10^{24}\,\mbox{kg})}{(6371.01\,\mbox{km})^2} \\ * &=& 9.82066032\,\mbox{m/s}^2 * \f} * * * Documentacion sobre la cual se basa la clase o archivo(s) que hagan una descripcion de la * misma: Archivo.doc * * Descripcion breve del ejemplo de uso de esta clase (este archivo se supone que estara en * una carpeta de nombre ./Examples en la actual posicion del codigo) * * Algo de latex * * The distance between \f$(x_1,y_1)\f$ and \f$(x_2,y_2)\f$ is \f$\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}\f$. * * @example ExampleText.cpp */ #endif Adicionalmente es deseable que algunos comportamientos o clases tengan informacion adicional como son: proposito, entradas, salidas, estructuras de datos usadas en entradas y salidas, dependencia de datos o ejecución, restricciones, etc., usando una estructura como la siguiente: /** * Purpose and Method: [include the physics if appropriate] * Inputs * Outputs * TDS Inputs * TDS Outputs * Dependencies: * Restrictions and Caveats: e.g. "This doesn't work off-axis" */ Para controlar las versiones se podria usar algo como lo siguiente: /** * @file release.notes * @brief Package TkrRecon * @verbatim * Coordinator: Leon Rochester * * v4r4p8 09-Mar-2002 LSR Remove GFxxxxx and SiRecObjs, no longer used * v4r4p7 07-Mar-2002 TU Mainly, add a combo vertexing to the TkrRecon sequence * @endverbatim */ Un ejemplo completo puede ser el siguiente: ********************************************************************************************** #ifndef __ErrorControl__ #define __ErrorControl__ #include using namespace std; #include #include "Printf.hpp" #ifdef USE_HYPRE #include #endif /// Error Control, this class handles errors for the system RESSIM /** * @author Antonio Carrillo and Gerardo Cisneros * @date Winter 2010 * @version 0.0.2 * @verbatim Coordinator: Rober Yates v0.0.1 Junuary 2011 Antonio Carrillo generates the first version of the class v0.0.2 March 2011 Gerardo Cisneros add HYPRE errors control Inputs: Name of class and function Outputs: Exit of program TDS Inputs: none TDS Outputs: none Dependencies: #ifdef USE_HYPRE, MPI package Restrictions and Caveats: Non exception handling still @endverbatim * @bug No errors detected * @warning No warnings detected * @todo Exception handling */ class ErrorControl { private: /// Name of class const char *nmClass; /// Name of function generating the error const char *nmFunction; public: /** * Class Constructor */ ErrorControl(void) { nameClassFunct(" ", " "); } /** * Class Constructor * @param clas Class name */ ErrorControl(const char *clas) { nameClassFunct(clas, " "); } /** * Class Constructor * @param clas Class name * @param fun Name of function generating the error */ ErrorControl(const char *clas, const char *fun) { nameClassFunct(clas, fun); } /** * Name of class and function * @param clas Class name * @param func Name of function generating the error */ void nameClassFunct(const char * clas, const char *func) { nameClass(clas); nameFunct(func); } /** * No memory for this request * @param var Var name */ void memoryError(const char * var) { Afprintf(stderr, "\n\nNo memory for %s request in %s of class %s\n\n", var, nmFunction, nmClass); fatalError(1); } /** * No memory for this request * @param var Var name * @param i Index number */ void memoryError(const char * var, int i) { Afprintf(stderr, "\n\nNo memory for %s request %d in %s of class %s\n\n", var, i, nmFunction, nmClass); fatalError(1); } /** * No memory for this request * @param var Var name * @param func Name of function generating the error */ void memoryError(const char * var, const char *func) { Afprintf(stderr, "\n\nNo memory for %s request in %s of class %s\n\n", var, func, nmClass); fatalError(1); } /** * Fatal error. * @param cod Error code */ void fatalError(int cod) { Afprintf(stderr, "\nFatal Error\nEnd program\n"); #ifdef USE_HYPRE MPI_Abort(MPI_COMM_WORLD, cod); #else exit(cod); #endif } /** * Fatal error. * @param cod Error code */ void fatalError(int cod, const char *txt) { Afprintf(stderr, txt); Afprintf(stderr, "\nFatal Error\nEnd program\n"); #ifdef USE_HYPRE MPI_Abort(MPI_COMM_WORLD, cod); #else exit(cod); #endif } /** * Set name of class * @param clas Class name */ void nameClass(const char *clas) { nmClass = clas; } /** * Set name of function * @param func Function name */ void nameFunct(const char *func) { nmFunction = func; } }; /** * Error Control, this class handles errors for the system RESSIM * * Use of the class ErrorControl for error handling within the system RESSIM, * for example in the error control of memory request * * @example ExampleErrorControl.cpp */ #endif ********************************************************************************************** Mas detalles sobre los parametros en la documentacion del codigo fuente para ser usada por DOXYGEN en: http://www.stack.nl/~dimitri/doxygen/commands.html#cmdparam http://www.dealii.org/developer/doxygen/tutorial/index.html ------------------------------------------------------------------------------------------------------- Algo de linux: http://www.mmc.geofisica.unam.mx/acl/linux/ Antonio Carrillo Ledesma http://www.mmc.geofisica.unam.mx/acl/