The output stage is where EDoc++ generates useful information about exception propagation. The amount and style of the information generated depends on the output format chosen.
There are a number of different output formats that EDoc++ will generate. In future versions it is planned to provide a plugin interface so that users can easily write additional output format plugins.
Currently three output formats are available. All output data be it in the doxygen, simple-doxygen or simple formats is by default sent to stdout. Instead of doing this, the user can specify the command line option "--output <filename>" in order to send the data to a file instead of stdout. One other point to note is that by default only functions that throw exceptions have output documentation generated for them. If you desire to see all functions even if they do not throw any exceptions then specify the --show-all option to edoc.
For the following sections we will continue using the
src/apps/simple/
application from Example Project.
EDoc application command line argument: --format simple
This format is primarily used by the Unit Tests. It can be useful to give an overall view of what is happening, however the data is not well presented for users to read and it also does not give as much information as the Doxygen format.
The simple format basically works by having a new line for a new item of data. Each line starts with an identifier that indicates what type of data is on that line. The following identifiers exist:
F: Function with an implementation
V: Pure virtual function
U: Undefined function (No Implementation)
L: Functions link name (As opposed to declared name)
E: Propagating exception
O: Originating exception
P: Possible exception
To demonstrate we will continue using the
src/apps/simple/
application from Example Project. Lets generate exception
documentation for that program in the simple format.
edoc --show-all --format simple simple.edc
Will produce the following output:
edoc --disable-auto-import --show-all --format simple simple.edc F: Function1() O: Exception O: FileException O: int F: Function2() O: FileException E: Exception - Function1() E: FileException - Function1() E: int - Function1() F: Function3() O: float P: Exception - Function1() P: FileException - Function1() P: int - Function1() E: FileException - Function2() E: FileException - Function2() E: Exception - Function2() E: int - Function2() F: main()
The first thing to notice is that our functions:
Function1()
, Function2()
,
Function3()
and main()
were listed in the
output. The main()
function does not have any exceptions
listed below it which means that if called it will not throw any
exceptions at all. Where you will see that Function1()
has listed below it a line like:
O: int
This means that Function1()
throws an exception of
type int. The throw statement for it is actually part of the
Function1()
code and is called an "Originating"
exception.
Function2()
also lists a line below it that is
like:
E: int - Function1()
This means that Function2()
can throw an exception
of type int. However unlike Function1()
this exception
does not originate from this function, but rather has entered this
function due to a call it made to Function1()
. This is
called a "Propagating Exception" as it propogates from a different
function to this one.
Function3()
lists a line like:
P: int - Function1()
This
means that Function3()
MAY throw an exception of type int
as a result of a call to Function1()
These "Possible"
Propogating exceptions occurr as a result of a function pointer call
or a call to a virtual function. In such situations, it is not
possible to determine exactly which function may be executed, so we
list exceptions for all functions that may possibly be called as
possible propogating exceptions.
EDoc application command line argument: --format
simple-doxygen
The Simple Doxygen format provides information in a format that can be processed directly by doxygen. This format provides a minimal amount of information that should be useful for creating API documentation. In particular for each function it will display a simple list of the types of exceptions a function may throw as a result of calling it.
Try generating simple-doxygen format data for our example:
edoc --format simple-doxygen simple.edc
Note:
We removed the --show-all
flag so it
will omit displaying any documentation for functions that have no
useful exception information. As a result edoc will display the
following:
edoc --disable-auto-import --format simple-doxygen simple.edc /*! \fn Function1() * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception Exception * \exception FileException * \exception int */ /*! \fn Function2() * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception Exception * \exception FileException * \exception int */ /*! \fn Function3() * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception Exception * \exception FileException * \exception float * \exception int */
Some import things to note. All doxygen formats currently have a
"\brief (BRIEF DESC NOT PROVIDED)
" and a "\note
EDoc++ data included
." line. These two lines do not give much
in the way of exception information but are currently necessary. The
first is necessary for the patched doxygen to be able to successfully
accept the following documentation as documentation belonging to the
functions detail section by first provided an unused brief
section.
When parsing source files for documentation the modified doxygen will only keep the first brief documentation segment it encounters for a particular code element. This means that when our file is processed after all other source files. The brief statements here should be overlooked. However it is still necessary for doxygen to consider the documentation following as valid documentation for the details section. This limitation may be removed in the future.
The second item is a doxygen note section. This can be used to indicate in the documentation that a function has actually been processed using EDoc++. This is helpful in order to see any possible "Holes" in the documentation due to limitations in the interface between EDoc++ and doxygen. See the later section on Running Doxygen
EDoc application command line argument: --format doxygen
The Doxygen format provides information in a format that can be processed directly by doxygen. This format is grouped in such a way that it makes it easier for the user to read.
The Doxygen output format shows the following information:
Name of function
List of all exceptions that may result from calling the function
For each exception it lists the place where that exception originates from.
For each originating exception it lists how that exception entered this function (Originates from this function OR another function that was called from which it entered this function).
A list of places within this function where the exception may have been "rethrown" from.
Try generating doxygen format data for our example:
edoc --format doxygen simple.edc
We
are only showing the documentation for Function3()
below
in order to explain its format.
EDOC -> EDOC -> $ edoc --disable-auto-import --format doxygen simple.edc -- ONLY SHOWING FUNCTION 3 -- /*! \fn Function3() * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception Exception * - Originating from: Function1() * - P: Function1() * - E: Function2() * . * . * <hr> * \exception FileException * - Originating from: Function1() * - P: Function1() * - E: Function2() * Rethrown: 1 times. Lines: ?? * . * - Originating from: Function2() * - E: Function2() * Rethrown: 1 times. Lines: ?? * . * . * <hr> * \exception float * - Originating from: Function3() * - O: Function3() * . * . * <hr> * \exception int * - Originating from: Function1() * - P: Function1() * - E: Function2() * . * . * <hr> */
The documentation for Function3()
covers all
possible output structures for the Doxygen output. We will break this
output down in order to understand exactly what it is
describing.
Firstly notice that from calling Function3()
four
different types of exceptions may result: Exception
,
FileException
, float
and
int
.
You will notice that it contains a single Originating from
block. This says that the exception of type "Exception
"
is originally thrown from a single place: Function1()
You can see that by looking at the code. I.e. There is only a single
"throw Exception();
" line in the code and that is in
Function1()
.
Underneath the Originating from block there are two lines:
P: Function1() E: Function2()
These lines tell us how the given exception
enters Function3()
. The letter at the start of the line
indicates one of:
O : Originates from function
E : Propagates from calling function
P : POSSIBLY propagates from calling function
The P line tells us that exception type
"Exception
" originating from Function1()
can enter Function3()
by a POSSIBLE function call to
Function1()
. Looking at the code this is what happens.
Function3()
calls a function pointer which has been
initialized with the address of Function1()
. This is
considered a possible call as it is possible that the function
pointer have other values too in which case any other function whose
addresses have been taken would also be used as possible function
calls.
The E line tells us that exception type
"Exception
" originating from Function1()
can also enter Function3()
by a definite function call
to Function2()
.
In our code we see that Function3()
calls
Function2()
which calls Function1()
and
thus we get this exception.
Much is similar to exception type "Exception
"
except there are two main differences.
The FileException
originating from
Function2()
has a "Rethrown" line. This indicates that
a FileException
entered Function3()
by a
call to Function2()
however it was caught in a catch
statement somewhere in Function3()
and then rethrown.
This occurred once in Function3()
. You can see that in
the code above.
Also we see that there are two "Originating from" blocks for
FileException
. This means that there are two locations
that a FileException
may originally be thrown from. The
first is in Function1()
and the second is in
Function2()
. Again you can see that there are two lines
in the code that look like: "throw FileException();
"
one in Function1()
and the other in
Function2()
.
You can notice from the float exception that there is one little difference here. The exception of type float originates from Function3(). This shows that. The originating from block lists Function3() and the line below showing where the exception entered Function3() indicates that it "O"riginated from Function3().
Errors and warnings are used to notify the user of a number of anomalies that may occur while processing EDoc++ data. It is helpful to note that all errors/warnings are displayed to the standard error stream and all follow a standard output format that should be easily parseable.
The error/warning format looks like:
WARNING(<warning-code>): Summary [: More details] ERROR(<error-code>): Summary [: More details]
The errors/warnings should be looked at as they can give hints to problems that may occur due to dangerous usage of exceptions. Below is a complete list of Errors/Warnings and descriptions of what causes them.
@@@Brendon TODO Add extra documentation indicating example code or usages that may cause these to occur.
ENOT_THROW
A must-not-throw block of code may propagate an exception.
ECRASH_SPEC
Exception may propagate through restrictive specifier.
ECRASH_THROW
Rethrow may occur outside catch block.
ECRASH_STATIC
An exception may propagate out to a static initialiser.
EMERGE
Failed to merge dictionaries
EMAIN_EXC
An exception may propagate out the main function.
EUSUPP_EXC
An exception may propagate through a function that was compiled with the -fno-exceptions flag.
WDIFF_THROW
Function has differing throw specifiers.
WDIFF_IMPL
Two functions with vague linkage have differing implementations.
WUNUSED_CATCH
Catch block never entered.
WSET_UNEXPECTED
The std::set_unexpected function is being used but is not yet supported by EDoc++
WDUP_TYPE
Duplicate type
WDUP_FUNC
Duplicate function
WUNIMPL
Function used but no implementation found
WMULT_IMPL
Function has multiple implementations
WINVALID_FILE
Invalid optional input file
WDESTR_EXC
An exception may propogate through a destructor