Doxygen -- part 2
Posted jakio6
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Doxygen -- part 2相关的知识,希望对你有一定的参考价值。
Documenting the code
这个章节涵盖两个主题:
- 如何在你的代码中放置注释, 一遍doxygen可以在生成的文档中囊括它们.
- 如何组织一个注释块的内容, 以使得输出美观.
特殊注释块
一个特殊注释块是一个带有一些额外标记,使得doxygen知道其是一段需要出现在生成的文档
中的结构化文本的C注释块.
对于Python, VHDL, Fortran以及Tcl代码, 有额外的注释约定, 可以xxx
C类语言的注释块
对于代码中的每个实体, 有两种(某些情况下有三种)类型的描述, 一起构成了那个实体的文
档, 一个brief
描述, 以及一个detailed
描述, 都是可选的. 对于方法和函数, 有第三
种类型的描述, 称作in body描述, 由在方法或者函数中找到的所有注释块共同组成.
可以有不止一个brief或者detailed描述(但是不推荐, 因为出现的顺序是没有指定的)
如果其名称所指, brief描述是一个简短, detailed, xx. in body描述也可以作为详细描述
或者描述一组实现细节. 对于html输出brief描述也用于提供在引用它的位置提供tooltip.
有数种方式将注释块标注为detailed描述:
- 使用Javadoc风格
/**
* ... text ...
*/
- 使用Qt风格, 并加个
!
:
/*!
* ... text ...
*/
- xxx
///
/// ... text ...
///
或者
//!
//!... text ...
//!
...
对于brief描述, 还有一些可能性:
- 在上面的注释块中使用
reif
命令. 这个命令在一个段落结束的时候结束, 因此在一
个空行之后是详细描述, 示例:
/*! rief Brief description.
* Brief description continued.
*
* Detailed description starts here.
*/
- 如果配置文件中
JAVADOC_AUTOBRIEF
设置为YES, 则使用Javadoc风格的注释块会自动开
始一个brief描述, 在一个跟有空格或者换行的.
的时候结束. 示例:
/** Brief description which ends at this dot. Details follow
* here.
*/
- 第三个选项, 是使用一个特殊的C++风格的注释(不跨多行), 示例:
/// Brief description.
/** Detailed description. */
或者
//! Brief description.
//! Detailed description
//! starts here.
如你所见, doxygen相当灵活. 如果你有多个详细描述, 像下面这样:
//! Brief description, which is
//! really a detailed description since it spans multiple lines.
/*! Another detailed description!
*/
它们会被合并. 在描述是在代码的不同位置的时候也是如此. 在这个例子中, 顺序取决于
doxygen解析代码的顺序
和许多其他的文档系统不同, doxygen还允许你将成员的文档置于定义之前. 这样, 文档可
以置于源文件中, 而不是头文件中. 这可以保持头文件精炼, 并且允许成员的实现者对文档
更直接的访问. 作为一种折中, brief描述可以置于在成员定义之前的详细描述之前.
在成员之后加文档
如果你想要记录一个文件, 结构体, 联合, 类, 枚举的成员, 有时会想要将文档块置于成员
之前或者之后. 出于这个意图, 你可以将一个额外的<
标记置于注释块中. 这对函数的参
数也是有用的.
这里是一些例子:
int var; /*!< Detailed description after the member */
这个块可以用于将Qt风格的详细文档块置于成员之后. 其他相同效果的还有:
int var; /**< Detailed description after the member */
或者
int var; //!< Detailed description after the member
//!<
或者
int var; ///< Detailed description after the member
///<
多数时候, 想要的只是, 将brief描述置于一个成员之后. 这是通过如下完成的:
int var; //!< Brief description after the member
或者
int var; ///< Brief description after the member
对于函数, 也可以使用@param
命令来记录参数, 使用[in]
,[out]
,[in,out
来记录方
向. 对于内联文档, 这个文档, 可以通过以方向数据开始来完成:
void foo(int v /**< [in] docs for input parameter v. */);
这些块的的结构和含义和前面的特殊块是一样的, 只有<
表明成员是位于块之前, 而不是
位于块(注释块)之后.
这个是一个使用这些注释块的例子:
/*! A test class */
class Afterdoc_Test
{
public:
/** An enum type.
* The documentation block cannot be put after the enum!
*/
enum EnumType
{
int EVal1, /**< enum value 1 */
int EVal2 /**< enum value 2 */
};
void member(); //!< a member function.
protected:
int value; /*!< an integer value */
};
示例
这是使用Qt风格注释C++代码块:
//! A test class.
/*!
A more elaborate class description.
*/
class QTstyle_Test
{
public:
//! An enum.
/*! More detailed enum description. */
enum TEnum {
TVal1, /*!< Enum value TVal1. */
TVal2, /*!< Enum value TVal2. */
TVal3 /*!< Enum value TVal3. */
}
//! Enum pointer.
/*! Details. */
*enumPtr,
//! Enum variable.
/*! Details. */
enumVar;
//! A constructor.
/*!
A more elaborate description of the constructor.
*/
QTstyle_Test();
//! A destructor.
/*!
A more elaborate description of the destructor.
*/
~QTstyle_Test();
//! A normal member taking two arguments and returning an integer value.
/*!
param a an integer argument.
param s a constant character pointer.
eturn The test results
sa QTstyle_Test(), ~QTstyle_Test(), testMeToo() and publicVar()
*/
int testMe(int a,const char *s);
//! A pure virtual member.
/*!
sa testMe()
param c1 the first argument.
param c2 the second argument.
*/
virtual void testMeToo(char c1,char c2) = 0;
//! A public variable.
/*!
Details.
*/
int publicVar;
//! A function variable.
/*!
Details.
*/
int (*handler)(int a,int b);
};
breif描述也包括在class,namespace,或者file的成员概览之中, 并且使用下号的斜体字.(
这个描述可以通过在配置文件中设置BRIEF_MEMBER_DESC
为NO来隐藏). 默认情况下brief
描述成为详细描述中的第一个句子(这个可以通过将REPEAT_BRIEF
tag设置为NO更改). 对
于Qt风格, 简要描述和详细描述都是可选的.
默认情况下Javadoc风格文档块和Qt风格文档块行为是一样的. 但是按照Javadoc指定却不是
如此, 按照规范, 第一个句子会自动当做简要描述. 要启用这个特性需要将
JAVADOC_AUTOBRIEF
设置为YES. 如果你启用这个选项并且想要在句子中加入一个dot而不
结束它, 你应该要其之后加. 这是一个例子:
/** Brief description (e.g. using only a few words). Details follow. */
这是和上面一样的代码块, 这次是使用Javadoc风格, 并且启用了JAVADOC_AUTOBRIEF
:
/**
* A test class. A more elaborate class description.
*/
class Javadoc_Test
{
public:
/**
* An enum.
* More detailed enum description.
*/
enum TEnum {
TVal1, /**< enum value TVal1. */
TVal2, /**< enum value TVal2. */
TVal3 /**< enum value TVal3. */
}
*enumPtr, /**< enum pointer. Details. */
enumVar; /**< enum variable. Details. */
/**
* A constructor.
* A more elaborate description of the constructor.
*/
Javadoc_Test();
/**
* A destructor.
* A more elaborate description of the destructor.
*/
~Javadoc_Test();
/**
* a normal member taking two arguments and returning an integer value.
* @param a an integer argument.
* @param s a constant character pointer.
* @see Javadoc_Test()
* @see ~Javadoc_Test()
* @see testMeToo()
* @see publicVar()
* @return The test results
*/
int testMe(int a,const char *s);
/**
* A pure virtual member.
* @see testMe()
* @param c1 the first argument.
* @param c2 the second argument.
*/
virtual void testMeToo(char c1,char c2) = 0;
/**
* a public variable.
* Details.
*/
int publicVar;
/**
* a function variable.
* Details.
*/
int (*handler)(int a,int b);
};
类似的, 如果想要Qt风格文档块的第一个句子自动当做breif描述, 可以设置
QT_AUTOBRIEF
.
在别的位置记录
在前面章节的例子中, 注释块总是位于文件, 类, 名称空间的声明或者定义之前, 或者在其
一个成员之前或者之后. 尽管这通常很方便, 有时也需要将文档置于别处. 对于文件记录,
这更是必要的, 因此不存在"in front of a file"这样的东西.
Doxygen允许你将你的文档块置于任何地方(除了在一个函数的body之中或者在一个寻常的C
风格注释中.
不将文档块直接置于一个item之前或者之后的代价是, 需要在文档块之中放置一个结构化命
令, 这会导致一些信息的重复.. 因此通常你应该避免使用结构化命令, 除非有其他要求使
得你不得不如此.
结构化命令由开始, 或者
@
, 如果你偏好Javadoc风格的话, 在加上一个命令名称以及
一个或者多个参数, 比如, 如果你想要记录类Test, 你可以将下面的文档置于doxygen读取
的输入中的某处:
/*! class Test
rief A test class.
A more detailed class description.
*/
在这里, 特殊命令class
用于表明注释块包含类Test的文档. 其他的结构化命令是:
struct
来记录C结构体union
来记录unionenum
来记录枚举类型fn
来记录函数文档var
来记录变量或者typedef或者枚举值def
来记录#define
file
来记录文件amespace
来记录名称空间package
来记录java packageinterface
来记录IDL接口
要记录一个C++类的成员, 你需要先记录这个类. 对于名称空间也是如此. 要记录全局C函数
, typedef, enum或者预处理器定义, 你必须先记录包含它的文件(通常是一个头文件, 因为
那个文件包含导出到其他源文件的信息).
再重复一遍, 要记录全局对象, 必须先记录他们所在的文件, 换句话说, 必须要有
/*! file */
或者/** @file */
这是一个例子:
/*! file structcmd.h
rief A Documented file.
Details.
*/
/*! def MAX(a,b)
rief A macro that returns the maximum of a a and a b.
Details.
*/
/*! var typedef unsigned int UINT32
rief A type definition for a .
Details.
*/
/*! var int errno
rief Contains the last error code.
warning Not thread safe!
*/
/*! fn int open(const char *pathname,int flags)
rief Opens a file descriptor.
param pathname The name of the descriptor.
param flags Opening flags.
*/
/*! fn int close(int fd)
rief Closes the file descriptor a fd.
param fd The descriptor to close.
*/
/*! fn size_t write(int fd,const char *buf, size_t count)
rief Writes a count bytes from a buf to the filedescriptor a fd.
param fd The descriptor to write to.
param buf The data buffer to write.
param count The number of bytes to write.
*/
/*! fn int read(int fd,char *buf,size_t count)
rief Read bytes from a file descriptor.
param fd The descriptor to read from.
param buf The buffer to read into.
param count The number of bytes to read.
*/
#define MAX(a,b) (((a)>(b))?(a):(b))
typedef unsigned int UINT32;
int errno;
int open(const char *,int);
int close(int);
size_t write(int,const char *, size_t);
int read(int,char *,size_t);
由于上面的例子中每个注释块包含一个结构化命令, 所有的注释块可以移到另一个位置或者
输入文件(比如源文件), 而不影响生成的文档. 缺点是, 原型会重复, 因此所有的改变需要
进行两次. 由于这个原因, 你应该首先考虑这是不是真的需要, 尽可能避免结构化命令. 我
通常碰到在一个函数之前放置包含fn
命令的注释块的例子. 明显fn
命令是赘余的, 只
会导致问题.
当你在以.dox
,.txt
或者.doc
结尾的文件中放置注释块的时候, doxygen会从文件列表
中隐藏这个文件...
如果你有一个doxygen不能解析, 但是仍然想要记录的话, 可以使用verbinclude
原样显
示它..:
/*! file myscript.sh
* Look at this nice script:
* verbinclude myscript.sh
*/
确保这个脚本在INPUT中明确列出或者FILE_PATTERNS
中包含.sh
拓展, 并且脚本可以在
EXAMPLE_PATH
设置的路径中找到.
详解注释块
先前的章节注重如何让doxygen获取你代码中的注释, 其解释了简要和详细描述之前的差异,
以及结构化命令的使用.
在这一节我们主要关注注释块的内容.
Doxygen支持多种格式化注释的风格.
最简单的是纯文本. 在输出中原样输出, 适用于短的描述
对于长的描述, 你通常会需要更多的结构, 比如, 原因输出的文本块, 或者一个简单的
table. doxygen支持Markdown语法来用作这个用途, 包括部分Markdown Extra拓展
对于变成语言特定的格式话, doxygen在Markdown之上还支持两种形式的额外标记.
- Javadoc类似的标记..
- XML标记, 如同C#标准中指定的...??
如果这还不够的话, doxygen还支持HTML标记语言的一个子集
!-->!-->以上是关于Doxygen -- part 2的主要内容,如果未能解决你的问题,请参考以下文章