Completing the example project

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.

Generating doxygen documentation

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.

Checking exception safety of library_user app

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