After covering all the details about how to use suppressions lets complete the goals set out in section: Goals for Example Project as set out for the example project.
In the documentation we will generate for the example project we
do not want to include exceptions that may be thrown by STL or any
exceptions derived from BugException which is used for assertions. So
lets modify our suppressions file to remove those exceptions from the
output. Change into the
$HOME/build/install_example/lib
directory
Lets create a small suppressions file that will filter out those exceptions and suppress the WUNUSED_CATCH warnings.
# example_libs.eds import eh def DisplayNotification(event): # Filter out ALL WUNUSED_CATCH warnings as we really dont care about them if event.Match(event='WUNUSED_CATCH'): return False # Filter out ALL WDIFF_THROW warnings as it is not important for this example if event.Match(event='WDIFF_THROW'): return False return True def PreExpansion(): # Dont show any BugException exceptions. eh.types.CaughtBy(eh.types.MatchesKey('BugException')).Suppress() # Suppress all functions starting with a _ (static initialisers and builtins) eh.functions.MatchesDeclared('^_.*').Suppress() # Suppress all functions declared in files that do not have the word # "example" within the name of the file they declared in. # For this project that will filter out functions defined in system header # files etc for k,v in eh.functions.items.items(): if v.loc.file.GetName().find('example') == -1: v.visible = False
and then we will run edoc getting it to generate the doxygen documentation while combining the libraries so we generate the documentation for them all at once:
edoc libmystatic.a libmyshared.so.0.0.0 libriddled.a --format doxygen example_libs.eds
this will display:
edoc --disable-auto-import libmystatic.a libmyshared.so libriddled.a --format doxygen /home/bcosta/dev/edoc/example/src/libs/example_libs.eds Logs going to file: /tmp/edoc_KaR2Dt /*! \fn GoBetween() * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception ExampleException * - Originating from: Riddled() * - E: Riddled() * . * . * <hr> * \exception Exception * - Originating from: Riddled() * - E: Riddled() * . * . * <hr> * \exception Throwable * - Originating from: Riddled() * - E: Riddled() * . * . * <hr> * \exception UnusedException * - Originating from: Riddled() * - E: Riddled() * . * . * <hr> */ /*! \fn Riddled() * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception ExampleException * - Originating from: Riddled() * - O: Riddled() * . * . * <hr> * \exception Exception * - Originating from: Riddled() * - O: Riddled() * . * . * <hr> * \exception Throwable * - Originating from: Riddled() * - O: Riddled() * . * . * <hr> * \exception UnusedException * - Originating from: Riddled() * - O: Riddled() * . * . * <hr> */ /*! \fn SomeClass::Function() * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception ExampleException * - Originating from: SomeClass::Function() * - O: SomeClass::Function() * . * . * <hr> */ /*! \fn ThrowOnCopy::ThrowOnCopy(ThrowOnCopy const&) * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception ExampleException * - Originating from: Riddled() * - E: GoBetween() * . * . * <hr> * \exception Exception * - Originating from: Riddled() * - E: GoBetween() * . * . * <hr> * \exception Throwable * - Originating from: Riddled() * - E: GoBetween() * . * . * <hr> * \exception UnusedException * - Originating from: Riddled() * - E: GoBetween() * . * - Originating from: ThrowOnCopy::ThrowOnCopy(ThrowOnCopy const&) * - O: ThrowOnCopy::ThrowOnCopy(ThrowOnCopy const&) * . * . * <hr> */ /*! \fn ThrowOnDestruction::~ThrowOnDestruction() * \brief (BRIEF DESC NOT PROVIDED). * * \note EDoc++ data included. * * \exception ExampleException * - Originating from: Riddled() * - E: Riddled() * Rethrown: 1 times. Lines: ?? * - E: GoBetween() * Rethrown: 1 times. Lines: ?? * . * . * <hr> * \exception Exception * - Originating from: Riddled() * - E: Riddled() * - E: GoBetween() * . * . * <hr> * \exception Throwable * - Originating from: Riddled() * - E: Riddled() * - E: GoBetween() * . * . * <hr> * \exception UnusedException * - Originating from: Riddled() * - E: Riddled() * - E: GoBetween() * . * . * <hr> * \exception char const[12] * - Originating from: ThrowOnDestruction::~ThrowOnDestruction() * - O: ThrowOnDestruction::~ThrowOnDestruction() * . * . * <hr> * \exception float * - Originating from: ThrowOnDestruction::~ThrowOnDestruction() * - O: ThrowOnDestruction::~ThrowOnDestruction() * . * . * <hr> * \exception int * - Originating from: ThrowOnDestruction::~ThrowOnDestruction() * - O: ThrowOnDestruction::~ThrowOnDestruction() * . * . * <hr> */ WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: int WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: float WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: char const[12] WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: ExampleException WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: ExampleException WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: Throwable WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: Exception WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: UnusedException WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: Throwable WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: Exception WARNING(WDESTR_EXC): An exception may propogate through a destructor. :Destructor: ThrowOnDestruction::~ThrowOnDestruction(), Exception: UnusedException
That was relatively painless. So we can now create the doxygen file by either redirecting the stdout or we will execute the program once more, this time specifying an output file for the doxygen documentation
edoc libmystatic.a libmyshared.so.0.0.0 libriddled.a --format doxygen example_libs.eds --output libs.dox
So lets copy the libs.dox file somewhere into the source tree where doxygen will find it and then run the doxygen command. This can be done from the build directory:
cp libs.dox $HOME/dev/edoc/edoc/data/example/src cd $HOME/build/example/src make doxygen-doc
This will create HTML documentation using
doxygen in the directory:
$HOME/build/example/src/doxygen-doc/html/index.html
This documentation is for the three libraries.
The final thing we wish to do for the example project is to check the exception safety of the library_user application. Checking exception safety is often more tedious to do than generating documentation. This is because to get accurate results you need to have EDoc++ data for all of the objects linked into the application (Including system calls). This is not strictly necessary but will ensure complete accuracy if done.
So lets run EDoc++ over the data required for the library_user application:
EDOC -> $ edoc -vv --check library_user ../lib/libmystatic.a ../lib/libmyshared.so ../lib/libriddled.a --additional /home/bcosta/build/install/edoc_patched/lib/libstdc++.so /home/bcosta/build/install/edoc_patched/lib/libgcc_s.so ... Loading information ... Applying Pre-Expansion suppressions... Expanding the callgraph... Applying Post-Expansion suppressions... Calculating propogating exceptions... ================================================================================ Applying Post_calculation suppressions... Checking exception specification lists... Checking for usage of functions that have no implementation... Checking for exceptions that propagate through static initialisers... Displaying exception information... ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: std::ios_base::failure may propagate out the main function which may cause a program abort. ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: std::bad_cast may propagate out the main function which may cause a program abort. ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: std::ios_base::failure may propagate out the main function which may cause a program abort. ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: std::bad_cast may propagate out the main function which may cause a program abort. ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: std::ios_base::failure may propagate out the main function which may cause a program abort. ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: std::bad_cast may propagate out the main function which may cause a program abort. ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: std::ios_base::failure may propagate out the main function which may cause a program abort. ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: std::bad_cast may propagate out the main function which may cause a program abort. ERROR(EMAIN_EXC): An exception may propogate out the main function. :The exception: Exception may propagate out the main function which may cause a program abort. WARNING(WUNIMPL): Function used but no implementation found : PluginIFace::Function() Done...
You will notice after running edoc that there are a number of exceptions that may propagate out the main function. Most of these are exceptions that occur from using STL which are very unlikely to occur. But there is one exception of type "Exception" that may crash the program. At this point you can choose to fix this problem by looking at what causes the exceptions and either catch them and handle the error appropriately or suppress or ignore them. The choice is up to the developer.
One other thing to notice is the warning. There was no implementation of PluginIFace::Function() found, but there was a call to it made. This is because EDoc++ cant find ANY implementations of the PluginIFace. The only implementation is in the plugin: myplugin whose EDoc++ data was not included in the above processing.
@@@Brendon One day update to add plugin data to the application