使用Doxygen
Doxygen是一个文档生成程序,被许多C/C++项目采用。它的主页在:http://www.doxygen.org。Sofia的文档也由Doxygen生成。
Doxygen的工作方式就是从C/C++代码中抽取文档数据以及特定的格式化注释。注释也包含一些类似于javadoc的特殊指令。
通常,注释和文档风格应当遵循javadoc风格指南:javadoc style guide。
一条Doxygen注释必须包含它正在描述的实体引用(reference)。例如,描述文件时使用指令@file:
/** * @file foo.c * * Implementation of foo. The foo takes care of grokking xyzzy. * * @author Jaska Jokunen <jaska.jokunen@company-email.address.hidden> \n * * @date Created: Wed Oct 20 15:06:51 EEST 2004 jasjoku */
通常,被文档化的实体紧跟在注释后。例如,文档化一个函数应当像如下所展示的这样:
/** * Orches a candometer. If orching candometer is not possible, it * tries to schadule hearping. * * @param[in] k pointer to a candometer * @param[in] level orching level * @param[out] return_hearping return value for schaduled hearping * * @return * The function orch() returns the candometer value, or #ERROR upon an error. * If the returned value is 0, the newly schaduled hearping is returned in * @a return_hearping. */ int orch(cando_t *k, int level, hearping_t *return_hearping) { ... }
doxygen可选项由配置文件Doxyfile指定。作为惯例,某个模块的Doxyfile文件都包含一个通用文件libsofia-sip-ua/docs/Doxyfile.conf。这使得保持模块特定的Doxyfiles尽可能整洁变得可能:
PROJECT_NAME = "ipt" OUTPUT_DIRECTORY = ../docs/ipt INPUT = ipt.docs . @INCLUDE = ../Doxyfile.conf TAGFILES += ../docs/docs/doxytags=../docs TAGFILES += ../docs/su/doxytags=../su GENERATE_TAGFILE = ../docs/ipt/doxytags
从上面这些内容可以观察到一些惯例。Doxygen生成的HMTL文档被放置在顶级目录下的docs子目录下。在docs目录下还将为每个子模块单独创建一个输出目录。在输出目录下针对特定模块的Doxytags被生成放置在doxytags文件内。
每个模块都有一个文档,至少包括一个名为<模块名称>.docs的文件。文件内应当包括一些样板化的信息,例如,下面所列的就是文件ipt.docs内的概要信息:
/** @MODULEPAGE "ipt" - Utility Module @section ipt_meta Module Meta Information Utility library for IP Telephony applications. @CONTACT Pekka Pessi <Pekka.Pessi@nokia-email.address.hidden> @STATUS @SofiaSIP Core library @LICENSE LGPL @section ipt_overview Overview This module contain some routines useful for IPT applications, like - ... - ... */
在这一小节,我们将回顾一遍大部分的Doxygen命令。所有命令在文档中均有说明。命令包括如下这些:
文本风格可通过如下指令更改:@b (粗体字), @c (代码),或 @e(斜体字) 。函数参数名使用风格命令@a。
例如,这句:"The Content-Type header ct specifies themedia-type of the message body, e.g.,audio/amr
would be AMR-encoded audio." 可以用如下所示命令生成
The @b Content-Type header @a ct specifies the @e media-type of the message body, e.g., @c audio/amr would be AMR-encoded audio.
风格命令可以用别名。例如,@em和@e的用途是相同的,@c和@p的用途也是一样的。.
用@param指令文档化函数参数(看看之前的一个orch()函数例子)。作为惯例,数据流方向在@param指令后给出,分别是[in], [out] or [in,out]。
返回值有两种方式表示。一,@return指令,二,retval指令。第二种方式在返回值是一些小数量的可能值时使用(这么翻译?)。例如,枚举类型值或者真假值。
/**Schadule hearping. * * The function schadule() schadules a hearping. * * @param[in] h pointer to hearping * * @retval 0 hearping was successful * @retval -1 an error occurred */ int schadule(hearping_t *h) { ... }
一个示例代码块可以被@code和@endcode指令包含。
/**Destroy a hearping. * * The function hearping_destroy() deinitializes a hearping and * reclaims the memory allocated for it. * * @param[in,out] h pointer to pointer to hearping * * The function clears the pointer to hearping, so it must be called * with a pointer to pointer: * @code * hearping_destroy(&x->hearping); * @endcode */ void hearping_destroy(hearping_t **h) {
@par指令被用来将文本分隔成各个段落。与@par指令处于同一行的其他文字作为段落的子标题。@date,@note,@bug,@todo,@sa (See Also)和@deprecated这些指令被用来向文档加入一些通用的段落。
在大部分文件里都有一个自身文件的文档入口(这句啥意思?)。In most files there is documentation entry for the file itself. 这个入口通常在文档的前部LGPL说明的后面,包括@file指令或者@CFILE/@IFILE。有一些Emacs宏可以用来创建这些范例入口。
当一篇文档的结构不依从于目录或者文件结构,可以使用分组指令@defgroup和@ingroup。@defgroup指令创建一个新组,@ingroup指令为组增加一个入口(这句啥意思?)。When the structure of the documentation does not follow directory or file structure, it is possible to use grouping commands @defgroup and @ingroup. The command @defgroup creates a group, and @ingroup adds an entry to an group.
通常,Doxygen在遇到结构体/类时会创建到它们的链接。同样可以为函数、类型名称和变量创建链接。如果函数名后只是一对括号,Doxygen会为函数创建链接。如果类型名称或者变量名前有#,Doxygen也会为它们创建链接。
可以用@link和@endlink指令创建到文档入口的链接,用自由选择链接的方式创建(这句啥意思?)。It is also possible to create links with freely selected link to documentation entries with @link and @endlink commands.
用@ref指令创建到目标为命名页、章节和子章节的链接。
一篇文档的主体由@mainpage指令指出。@mainpage入口包括的内容将成为文档集的HTML主页。用Doxygen生成的每个文档集中只能有一个@mainpage指令。@section,@subsection和@subsubsection指令可被用来结构化文档文字。
仍然可以为文档添加单独的HTML页面。可以用@page指令做到这点。这些独立的页面就像@mainpage指令增加的主页一样,他们可以通过导航栏的相关页面链接存取(这句啥意思?)。
使用@image指令添加图片。因为不同的文档格式支持不同的图片格式,所以@image指令为每个支持的文档格式指定特定的图片文件。下面的例子展示为HTML文档使用bitmap图片Encapsulate PostScript for print documents(这句啥意思?):
@image html sip-parser.gif @image latex sip-parser.eps