C++11 code comments and Doxygen document generation

Code comments and Doxygen document generation

1、Doxygen

Doxygen is a free (cost and license) tool that can read the source code and find comments that follow specific conditions. Build and extract information from comments and code to generate documentation. It outputs in multiple formats: HTML, RTF (Rich Text Format), LaTeX, UNIX man pages and XML.

Java programmers may be familiar with a similar tool called javadoc. The Javadoc tool is a standard tool in the Java Software Development Kit, and Doxygen has nothing to do with the C++ standard or any C++ vendor. C++ lacks a standard for structured documentation, so you are free to do whatever you want. For example, if you plan to work entirely in the Microsoft .NET environment, Microsoft will define its own conventions for XML tags in the comments, which is great. For other programmers, it is recommended to use more extensive and portable tools. The most popular solution is Doxygen, and I think that even if you decide not to use it, every C++ programmer should know this.

2. Structured content

Doxygen follows a specific format of comments.

  • Single-line comments begin with an extra slash or exclamation mark: /// or //!
  • Multi-line comments begin with an extra asterisk or exclamation mark: /** or /*!

Similarly, Doxygen recognizes some widely used annotation conventions and modifications. E.g. It ignores slashes on a line. E.g:


Multi-line comments can start with a line full of asterisks. E.g:

/**************************************************************
And a line in a multiline comment can begin with an asterisk.
/*************************************************************
This is a structured comment for Doxygen. 
*************************************************************/

In structured comments, you can record various entities in the program: functions, types, variables, etc.

By convention, the comment before the declaration or definition applies to the entity to be declared or defined. Sometimes it is desirable to add a comment after the declaration, such as a single-line description of the variable. To do this, please use the "less than" (<) symbol at the beginning of the comment content.

double const c = 299792458.0; ///< speed of light in m/sec

3. Document tags and Markdown

The commonly used tags in Doxygen are as follows:

  • @b word: Use boldface to mark words. HTML tags may also be used word </ b>, if the phrase contains spaces, or the Markdown, text enclosed in asterisks: *word*.
  • @brief one-sentence-description : A brief description of an entity, equivalent to a summary. The entity has short and detailed documentation. Depending on how Doxygen is configured, the brief document can be the first sentence of the entity's complete document, or a clear document **@brief** tag can be required. In either case, the rest of the content is the detailed documentation of the entity.
  • @c word: Treat word as a code snippet and set it as a fixed-space font. You can also use HTML tags, phrases </tt>, or use backticks for Markdown word.
  • @em word : Use italics for emphasis. You can also use HTML tags, word</ em> or Markdown underscore: word .
  • @file file name : Provides an overview of the source file. The detailed description can describe the purpose of the file, revision history, and other global documents. The file name is optional; without it, Doxygen will use the real name of the file.
  • @link entity text @endlink : Create a hyperlink to a named entity (such as a file).
  • @mainpage title : Provides an overview of the entire project on the index or cover page. You can put @mainpage in any source file, and you can even keep a separate file for comments. In small projects, you can put @mainpage in the same source file as the main function, but in large projects, it is recommended to use a separate file.
  • @p name : Set name in the fixed-pitch font to distinguish it as function parameters.
  • @par title : start a new paragraph. If a single-line heading is provided, it will become the paragraph heading. Blank lines also separate paragraphs.
  • @param name description : Record a function parameter named name. If you want to reference this parameter document elsewhere in the function, please use **@p name**.
  • @post postcondition : record the post condition of the function. The post-condition is a boolean expression, you can assume it is true when the function returns (assuming all the premises are true). C++ lacks any formal mechanism to enforce postconditions (rather than assertions), so it is important to record postconditions, especially for library writers.
  • @pre precondition : Record the preconditions of the function. The prerequisite is a Boolean expression, which must be true before the function is called, otherwise the normal operation of the function cannot be guaranteed. C++ lacks any mandatory formal mechanism preconditions (rather than assertions), so documenting preconditions is crucial, especially for library writers.
  • @return description : Record the return value description of the function.
  • @see xref : Insert a cross-reference to the entity named xref . Doxygen looks for structured comments with references to other documented entities inside. When it finds one, it inserts a hyperlink (or text cross-reference, depending on the output format). However, sometimes it is necessary to insert an explicit reference to an entity that is not named in the entity, so @see can be used. You can also prohibit the automatic creation of hyperlinks by adding% in front of the name.
  • @&, @@, @, @%, @< : escape text characters (&, @, \,% or <) to prevent interpretation by Doxygen or HTML.

Doxygen is very flexible, you can use a variety of ways to format comments using native Doxygen tags, HTML or Markdown. Examples are as follows:

/** @file
* @brief Test strings to see whether they are palindromes.
* Read lines from the input, strip non-letters, and check whether
* the result is a palindrome. Ignore case differences when checking.
* Echo palindromes to the standard output.
*/
/** @mainpage Palindromes
* Test input strings to see whether they are palindromes.
*
* A _palindrome_ is a string that reads the same forward and backward.
* To test for palindromes, this program needs to strip punctuation and
* other non-essential characters from the string, and compare letters without
* regard to case differences.
*
* This program reads lines of text from the standard input and echoes
* to the standard output those lines that are palindromes.
*
* Source file: [palindrome.cpp](palindrome.cpp)
*
* @date 27-July-2013
* @author Ray Lischner
* @version 2.0
*/
#include <algorithm>
#include <iostream>
#include <iterator>
#include <locale>
#include <string>
/** @brief Test for non-letter.
* Test the character @p ch in the global locale.
* @param ch the character to test
* @return true if @p ch is not a letter
*/
bool non_letter(char ch)
{
return not std::isalnum(ch, std::locale{});
}
/** @brief Convert to lowercase.
* Use a canonical form by converting to uppercase first,
* and then to lowercase. This approach does not solve the eszet
* problem (German eszet is a lowercase character that converts
* to two uppercase characters), but it's the best we can do in
* standard C++.
*
* All conversions use the global locale.
*
* @param ch the character to test
* @return the character converted to lowercase
*/
char lowercase(char ch)
{
return std::tolower(ch, std::locale{});
}
/** @brief Compare two characters without regard to case.
* The comparison is limited by the `lowercase()` function.
* @param a one character to compare
* @param b the other character to compare
* @return `true` if the characters are the same in lowercase,
* `false` if they are different.
*/
bool is_same_char(char a, char b)
{
return lowercase(a) == lowercase(b);
}
/** @brief Determine whether @p str is a palindrome.
* Only letter characters are tested. Spaces and punctuation don't count.
* Empty strings are not palindromes because that's just too easy.
* @param str the string to test
* @return `true` if @p str is the same forward and backward and
* `not str.empty()`
*/
bool is_palindrome(std::string str)
{
std::string::iterator end{std::remove_if(str.begin(), str.end(), non_letter)};
std::string rev{str.begin(), end};
std::reverse(rev.begin(), rev.end());
return not rev.empty() and std::equal(str.begin(), end, rev.begin(), is_same_char);
}
/** @brief Main program.
* Set the global locale to the user's native locale. Then imbue the I/O streams
* with the native locale.
*/
int main()
{
std::locale::global(std::locale{""});
    std::cin.imbue(std::locale{});
std::cout.imbue(std::locale{});
std::string line{};
while (std::getline(std::cin, line))
if (is_palindrome(line))
std::cout << line << '\n';
}

The generated documents are as follows:
Insert picture description here

Guess you like

Origin blog.csdn.net/wujuxKkoolerter/article/details/114112024