Files
unison/doc/manual/source/documentation.rst
Peter D. Barnes, Jr. 9e5633feff [Sphinx] fix error
2014-10-08 17:47:34 -07:00

580 lines
20 KiB
ReStructuredText

.. include:: replace.txt
.. highlight:: cpp
Creating Documentation
----------------------
|ns3| supplies two kinds of documentation: expository "user-guide"-style
chapters, and source code API documentation.
The "user-guide" chapters are written by hand in reStructuredText_
format (``.rst``), which is processed by the Python documentation
system Sphinx_ to generate web pages and pdf files.
The API documentation is generated from the source code itself,
using Doxygen_, to generate cross-linked web pages.
Both of these are important: the Sphinx chapters explain the *why*
and overview of using a model; the API documentation explains the
*how* details.
This chapter gives a quick overview of these
tools, emphasizing preferred usage and customizations for |ns3|.
To build all the standard documentation:
.. sourcecode:: bash
$ ./waf docs
For more specialized options, read on.
.. _reStructuredText: http://sphinx-doc.org/rest.html
.. _sphinx: http://sphinx-doc.org/
.. _doxygen: http://www.doxygen.org/
Documenting with Sphinx
***********************
We use Sphinx_ to generate expository chapters describing
the design and usage of each module. Right now you are reading the
:doc:`Documentation <documentation>` Chapter.
The `Show Source <_sources/documentation.txt>`_ link in the sidebar
will show you the reStructuredText source for this chapter.
Adding New Chapters
===================
Adding a new chapter takes three steps (described in more detail below):
#. Choose `Where?`_ the documentation file(s) will live.
#. `Link`_ from an existing page to the new documentation.
#. Add the new file to the `Makefile`_.
Where?
######
Documentation for a specific module, ``foo``, should normally go in
``src/foo/doc/``. For example ``src/foo/doc/foo.rst`` would be the
top-level document for the module. The ``src/create-module.py`` script
will create this file for you.
Some models require several ``.rst`` files, and figures; these should
all go in the ``src/foo/doc/`` directory. The docs are actually build
by a Sphinx Makefile. For especially involved
documentation, it may be helpful to have a local ``Makefile``
in the ``src/foo/doc/`` directory to
simplify building the documentation for this module
(`Antenna`_ is an example). Setting this up
is not particularly hard, but is beyond the scope of this chapter.
In some cases, documentation spans multiple models; the
`Network`_ chapter is an example. In these cases
adding the ``.rst`` files directly to ``doc/models/source/`` might
be appropriate.
.. _antenna: http://www.nsnam.org/docs/models/html/antenna.html
.. _network: http://www.nsnam.org/docs/models/html/network.html
Link
####
Sphinx has to know *where* your new chapter should appear. In most
cases, a new model chapter should appear the in `Models` book.
To add your chapter there, edit ``doc/models/source/index.rst``
.. sourcecode:: rest
.. toctree::
:maxdepth: 1
organization
animation
antenna
aodv
applications
...
Add the name of your document (without the ``.rst`` extension) to
this list. Please keep the Model chapters in alphabetical order,
to ease visual scanning for specific chapters.
Makefile
########
You also have to add your document to the appropriate ``Makefile``,
so ``make`` knows to check it for updates. The Models book Makefile
is ``doc/models/Makefile``, the Manual book Makefile is
``doc/manual/Makefile``.
.. sourcecode:: make
# list all model library .rst files that need to be copied to $SOURCETEMP
SOURCES = \
source/conf.py \
source/_static \
source/index.rst \
source/replace.txt \
source/organization.rst \
...
$(SRC)/antenna/doc/source/antenna.rst \
...
You add your ``.rst`` files to the ``SOURCES`` variable. To add figures,
read the comments in the ``Makefile`` to see which variable should contain
your image files. Again, please keep these in alphabetical order.
Building Sphinx Docs
====================
Building the Sphinx documentation is pretty simple.
To build all the Sphinx documentation:
.. sourcecode:: bash
$ ./waf sphinx
To build just the Models documentation:
.. sourcecode:: bash
$ make -C doc/models
To see the generated documentation point your browser at
``doc/models/build/html``.
As you can see, Sphinx uses Make to guide the process.
The default target builds all enabled output forms, which in
|ns3| are the multi-page ``html``, single-page ``singlehtml``, and pdf
(``latex``). To build just the multi-page html, you add the ``html`` target:
.. sourcecode:: bash
$ make -C doc/models html
This can be helpful to reduce the build time (and the size of the
build chatter) as you are writing your chapter.
Before committing your documentation to the repo, please check
that it builds without errors or warnings. The build process
generates lots of output (mostly normal chatter from LaTeX),
which can make it difficult to see if there are any Sphinx
warnings or errors. To find important warnings and errors
build just the ``html`` version, then search the build log
for ``warning`` or ``error``.
|ns3| Specifics
===============
The Sphinx documentation_ and tutorial_ are pretty good. We won't duplicate
the basics here, instead focusing on preferred usage for |ns3|.
.. _documentation: http://sphinx-doc.org/contents.html
.. _tutorial: http://sphinx-doc.org/tutorial.html
* Start documents with these two lines:
.. sourcecode:: rest
.. include:: replace.txt
.. highlight:: cpp
The first line enables some simple replacements. For example,
typing ``|ns3|`` renders as |ns3|.
The second sets the default source code highlighting language explicitly
for the file, since the parser guess isn't always accurate.
(It's also possible to set the language explicitly for a single code block,
see below.)
* Sections:
Sphinx is pretty liberal about marking section headings. By convention,
we prefer this hierarchy:
.. sourcecode:: rest
.. heading hierarchy:
------------- Chapter
************* Section (#.#)
============= Subsection (#.#.#)
############# Sub-subsection
* Syntax Highlighting:
To use the default syntax highlighter, simply start a sourcecode block:
+--------------------------------------+------------------------------------+
| Sphinx Source | Rendered Output |
+======================================+====================================+
| .. sourcecode:: rest | |
| | |
| The ``Frobnitz`` is accessed by:: | The ``Frobnitz`` is accessed by:: |
| | |
| Foo::Frobnitz frob; | Foo::Frobnitz frob; |
| frob.Set (...); | frob.Set (...); |
+--------------------------------------+------------------------------------+
To use a specific syntax highlighter, for example, ``bash`` shell commands:
+--------------------------------------+------------------------------------+
| Sphinx Source | Rendered Output |
+======================================+====================================+
| .. sourcecode:: rest | |
| | |
| .. sourcecode:: bash | .. sourcecode:: bash |
| | |
| $ ls | $ ls |
+--------------------------------------+------------------------------------+
* Shorthand Notations:
These shorthands are defined:
+--------------------------------------+------------------------------------+
| Sphinx Source | Rendered Output |
+======================================+====================================+
| .. sourcecode:: rest | |
| | |
| |ns3| | |ns3| |
+--------------------------------------+------------------------------------+
| .. sourcecode:: rest | |
| | |
| |ns2| | |ns2| |
+--------------------------------------+------------------------------------+
| .. sourcecode:: rest | |
| | |
| |check| | |check| |
+--------------------------------------+------------------------------------+
| .. sourcecode:: rest | |
| | |
| :rfc:`6282` | :rfc:`6282` |
+--------------------------------------+------------------------------------+
Documenting with Doxygen
************************
We use Doxygen_ to generate browsable_ API documentation. Doxygen
provides a number of useful features:
* Summary table of all class members.
* Graphs of inheritance and collaboration for all classes.
* Links to the source code imlementing each function.
* Links to every place a member is used.
* Links to every object used in implementing a function.
* Grouping of related classes, such as all the classes related to
a specific protocol.
In addition, we use the ``TypeId`` system to add to the documentation
for every class
* The ``Config`` paths by which such objects can be reached.
* Documentation for any ``Attributes``, including ``Attributes``
defined in parent classes.
* Documentation for any ``Trace`` sources defined by the class.
Doxygen operates by scaning the source code, looking for
specially marked comments. It also creates a cross reference,
indicating *where* each file, class, method, and variable is used.
.. _browsable: https://www.nsnam.org/docs/doxygen
Preferred Style
===============
The preferred style for Doxygen comments is the JavaDoc style::
/**
* Brief description of this class or method.
* Adjacent lines become a single paragraph.
*
* Longer description, with lots of details.
*
* Blank lines separate paragraphs.
*
* Explain what the class or method does, using what algorithm.
* Explain the units of arguments and return values.
*
* \note Note any limitations or gotchas.
*
* (For functions with arguments or return valued:)
* \param foo Brief noun phrase describing this argument.
* \param bar Note Sentence case, and terminating period.
* \return Brief noun phrase describing the value.
*
* \internal
*
* You can also discuss internal implementation details.
* Understanding this material shouldn't be necessary to using
* the class or method.
*/
class Example
In this style the Doxygen comment block begins with two \`*' characters:
``/**``, and precedes the item being documented.
For items needing only a brief description, either of these short forms
is appropriate::
/** Destructor implementation. */
void DoDispose ();
int m_count; //!< Count of ...
Note the special form of the end of line comment, ``//!<``, indicating
that it refers to the *preceding* item.
Some items to note:
* Use sentence case, including the initial capital.
* Use punctuation, especially \`.'s at the end of sentences or phrases.
* The ``\brief`` tag is not needed; the first sentence will be
used as the brief description.
Every class, method, typedef, member variable, function argument
and return value should be documented in all source code files
which form the formal API and implementation for |ns3|, such as
``src/<module>/model/*``, ``src/<module>/helper/*`` and
``src/<module>/utils/*``. Documentation for items in ``src/<module>/test/*``
and ``src/<module>/examples/*`` is preferred, but not required.
Useful Features
===============
* Inherited members will automatically inherit docs from the parent,
(but can be replaced by local documentation).
#. Document the base class.
#. In the sub class mark inherited functions with an ordinary comment::
// Inherited methods
virtual void FooBar (void);
virtual int BarFoo (double baz);
Note that the signatures have to match exactly, so include the formal
argument ``(void)``
This doesn't work for static functions; see ``GetTypeId``, below, for an
example.
Building Doxygen Docs
=====================
Building the Doxygen documentation is pretty simple:
.. sourcecode:: bash
$ ./waf doxygen
This builds using the default configuration, which generates documentation
sections for *all* items, even if they do not have explicit comment
documentation blocks. This has the effect of suppressing warnings for
undocumented items, but makes sure everything appears in the generated
output.
When writing documentation, it's often more useful to see which items
are generating warnings, typically about missing documentation.
To see the full warnings list, use the ``doc/doxygen.warnings.report.sh``
script:
.. sourcecode:: bash
$ doc/doxygen.warnings.report.sh
Waf: Entering directory `build'
...
Waf: Leaving directory `build'
'build' finished successfully (3m24.094s)
Rebuilding doxygen docs with full errors...Done.
Report of Doxygen warnings
----------------------------------------
(All counts are lower bounds.)
Warnings by module/directory:
Count Directory
----- ----------------------------------
3844 src/lte/model
1718 src/wimax/model
1423 src/core/model
....
138 additional undocumented parameters.
----------------------------------------
15765 total warnings
126 directories with warnings
Warnings by file (alphabetical)
Count File
----- ----------------------------------
17 doc/introspected-doxygen.h
15 examples/routing/manet-routing-compare.cc
26 examples/stats/wifi-example-apps.h
....
----------------------------------------
967 files with warnings
Warnings by file (numerical)
Count File
----- ----------------------------------
374 src/lte/model/lte-asn1-header.h
280 src/lte/model/lte-rrc-sap.h
262 src/lte/model/lte-rrc-header.h
....
----------------------------------------
967 files with warnings
Doxygen Warnings Summary
----------------------------------------
126 directories
967 files
15765 warnings
The script modifies the configuration to show all warnings, and
to shorten the run time. As you can see, at this writing we have
*a lot* of undocumented items. The report summarizes warnings
by module ``src/*/*``, and by file, in alphabetically and numerical
order.
The script has a few options to pare things down and make this more
manageable. For help, use the ``-h`` option. Having run it once
to do the Doxygen build and generate the full warnings log,
you can reprocess the log file with various "filters,"
without having to do the full Doxygen build by,
again using the ``-s`` option. You can exclude warnings
from ``*/examples/*`` files (``-e`` option), and/or ``*/test/*`` files
(``-t``).
Perhaps the most useful option when writing documentation comments
is ``-m <module>``, which will limit the report to just files matching
``src/<module>/*``, and follow the report with the actual warning lines.
Combine with ``-et`` and you can focus on the warnings that are most
urgent in a single module:
.. sourcecode:: bash
$ doc/doxygen.warnings.report.sh -m mesh/helper
...
Doxygen Warnings Summary
----------------------------------------
1 directories
3 files
149 warnings
Filtered Warnings
========================================
src/mesh/helper/dot11s/dot11s-installer.h:72: warning: Member m_root (variable) of class ns3::Dot11sStack is not documented.
src/mesh/helper/dot11s/dot11s-installer.h:35: warning: return type of member ns3::Dot11sStack::GetTypeId is not documented
src/mesh/helper/dot11s/dot11s-installer.h:56: warning: return type of member ns3::Dot11sStack::InstallStack is not documented
src/mesh/helper/flame/lfame-installer.h:40: warning: Member GetTypeId() (function) of class ns3::FlameStack is not documented.
src/mesh/helper/flame/flame-installer.h:60: warning: return type of member ns3::FlameStack::InstallStack is not documented
src/mesh/helper/mesh-helper.h:213: warning: Member m_nInterfaces (variable) of class ns3::MeshHelper is not documented.
src/mesh/helper/mesh-helper.h:214: warning: Member m_spreadChannelPolicy (variable) of class ns3::MeshHelper is not documented.
src/mesh/helper/mesh-helper.h:215: warning: Member m_stack (variable) of class ns3::MeshHelper is not documented.
src/mesh/helper/mesh-helper.h:216: warning: Member m_stackFactory (variable) of class ns3::MeshHelper is not documented.
src/mesh/helper/mesh-helper.h:209: warning: parameters of member ns3::MeshHelper::CreateInterface are not (all) documented
src/mesh/helper/mesh-helper.h:119: warning: parameters of member ns3::MeshHelper::SetStandard are not (all) documented
Now it's just a matter of understanding the code, and writing some
docs!
|ns3| Specifics
===============
As for Sphinx, the Doxygen docs_ and reference_ are pretty good.
We won't duplicate the basics here, instead focusing on preferred
usage for |ns3|.
.. _docs: http://www.stack.nl/~dimitri/doxygen/index.html
.. _reference: http://www.stack.nl/~dimitri/doxygen/manual/commands.html
* Use Doxygen ``Modules`` to group related items.
In the main header for a module, create a Doxgyen group::
/**
* \defgroup foo Foo protocol.
*/
Mark each associated class as belonging to the group::
/**
* \ingroup foo
*
* Foo packet type.
*/
class Foo
* Did you know ``typedefs`` can have formal arguments? This enables
documentation of function pointer signatures::
/**
* Bar callback function signature.
*
* \param ale The size of a pint of ale, in Imperial ounces.
*/
typedef void (* BarCallback)(const int ale);
* Copy the ``Attribute`` help strings from the ``GetTypeId`` method to use
as the brief descriptions of associated members.
* ``\bugid{298}`` will create a link to bug 298 in our Bugzilla.
* ``\pname{foo}`` in a description will format ``foo``
as a ``\param foo`` parameter, making it clear that you
are referring to an actual argument.
* ``\RFC{301}`` will create a link to RFC 301.
* ``\internal`` should be used only to set off a discussion of implementation
details, not to mark ``private`` functions (they are already marked,
as ``private``!)
* Don't create classes with trivial names, such as ``class A``,
even in test suites. These cause all instances of the class name
literal \`A' to be rendered as links.
As noted above, static functions don't inherit the documentation
of the same functions in the parent class. |ns3| uses a few static
functions ubiquitously; the suggested documentation block for these
cases is:
* Default constructor/destructor::
MyClass (); //!< Default constructor
~MyClass (); //!< Destructor
* Dummy destructor and DoDispose::
/** Dummy destructor, see DoDispose. */
~MyClass ();
/** Destructor implementation */
virtual void DoDispose ();
* GetTypeId::
/**
* Register this type.
* \return The object TypeId.
*/
static TypeId GetTypeId (void);