Overview docs for wrapper binary implementation
authorTeemu Murtola <teemu.murtola@gmail.com>
Wed, 1 Jan 2014 05:21:43 +0000 (07:21 +0200)
committerRoland Schulz <roland@rschulz.eu>
Thu, 30 Jan 2014 16:39:24 +0000 (17:39 +0100)
Add an overview of how the gmx wrapper binary is implemented.
Also some minor clean-up for related module documentation.
Remove test directories from public documentation.

Change-Id: If21cd14d189f239bed19def0acba43681013b0c6

doxygen/Doxyfile-user.cmakein
doxygen/directories.cpp
doxygen/mainpage.md
doxygen/wrapperbinary.md [new file with mode: 0644]
src/gromacs/commandline.h
src/gromacs/commandline/cmdlinemodulemanager.h
src/gromacs/onlinehelp.h [new file with mode: 0644]
src/gromacs/onlinehelp/helptopicinterface.h

index 84d67d9eac6b5e10dcd3cf4272c6555282811e88..4b368c4d842558bce7dcc1709f029d4ad73745a9 100644 (file)
@@ -4,6 +4,7 @@
 # exclude them from the generated file list
 EXCLUDE               += @CMAKE_SOURCE_DIR@/src/programs
 EXCLUDE               += @CMAKE_SOURCE_DIR@/src/testutils
+EXCLUDE               += @CMAKE_SOURCE_DIR@/doxygen/wrapperbinary.md
 
 INTERNAL_DOCS          = NO
 HIDE_UNDOC_CLASSES     = YES
index 6d0e380519d04bf954ceccecd51dd1976acf3e8f..0fb943690a5f26e67aef1d6c48950fc1829d9ca4 100644 (file)
@@ -28,7 +28,7 @@ Doxygen documentation file for directories in the source tree.
 
 \ingroup module_analysisdata
  */
-/*!
+/*! \libinternal
 \dir src/gromacs/analysisdata/tests
 \brief Unit tests for \ref module_analysisdata
 
@@ -41,20 +41,33 @@ Doxygen documentation file for directories in the source tree.
 
 \ingroup module_commandline
  */
-/*!
+/*! \libinternal
 \dir src/gromacs/commandline/tests
 \brief Unit tests for \ref module_commandline
 
 \ingroup module_commandline
  */
 
+/*!
+\dir src/gromacs/onlinehelp
+\brief \ref module_onlinehelp
+
+\ingroup module_onlinehelp
+ */
+/*! \libinternal
+\dir src/gromacs/onlinehelp/tests
+\brief Unit tests for \ref module_onlinehelp
+
+\ingroup module_onlinehelp
+ */
+
 /*!
 \dir src/gromacs/options
 \brief \ref module_options
 
 \ingroup module_options
  */
-/*!
+/*! \libinternal
 \dir src/gromacs/options/tests
 \brief Unit tests for \ref module_options
 
@@ -67,7 +80,7 @@ Doxygen documentation file for directories in the source tree.
 
 \ingroup module_selection
  */
-/*!
+/*! \libinternal
 \dir src/gromacs/selection/tests
 \brief Unit tests for \ref module_selection
 
@@ -80,7 +93,7 @@ Doxygen documentation file for directories in the source tree.
 
 \ingroup module_trajectoryanalysis
  */
-/*!
+/*! \libinternal
 \dir src/gromacs/trajectoryanalysis/tests
 \brief Unit tests for \ref module_trajectoryanalysis
 
@@ -93,7 +106,7 @@ Doxygen documentation file for directories in the source tree.
 
 \ingroup module_utility
  */
-/*!
+/*! \libinternal
 \dir src/gromacs/utility/tests
 \brief Unit tests for \ref module_utility
 
index 011f7cfb2b9d03e6ae0aebe07d451504d195ec30..62fab1f4f76e662ac1ec0f7f5fd23b07a171efd9 100644 (file)
@@ -56,6 +56,8 @@ give an overview of some of the topics that are documented:
    Provides general guidance for writing software that uses the \Gromacs
    library.
 \if libapi
+ - \subpage page_wrapperbinary <br/>
+   Provides an overview of how the `gmx` wrapper binary is implemented.
  - \subpage thread_mpi <br/>
    This code is used internally for threading support, and also provides a
    (partial) MPI implementation that allows compiling a "thread-MPI" version of
diff --git a/doxygen/wrapperbinary.md b/doxygen/wrapperbinary.md
new file mode 100644 (file)
index 0000000..8be4678
--- /dev/null
@@ -0,0 +1,129 @@
+Wrapper binary implementation {#page_wrapperbinary}
+=============================
+
+This page mainly describes the implementation of the `gmx` wrapper binary.
+Many of the details are not visible to most of the code, but this documentation
+is included as part of the library API documentation to make it easier to
+understand the overall implementation without reading extensive documentation.
+
+%main() implementation
+======================
+
+The %main() method for the wrapper binary is implemented in
+`src/programs/gmx/gmx.cpp`.  This is a very simple code that does these basic
+tasks:
+ 1. Initializes \Gromacs using gmx::initForCommandLine()
+    (see \ref page_usinglibrary).
+ 2. Creates a gmx::CommandLineModuleManager instance for the wrapper binary.
+ 3. Calls various methods to add modules to the manager and initialize it
+    otherwise.  Many of the pre-5.0 binaries are added from
+    `src/programs/gmx/legacymodules.cpp`.  New C++ tools are added from
+    `src/gromacs/trajectoryanalysis/modules.cpp`.
+ 4. Passes control to the manager (see below).
+ 5. On successful return, deinitializes \Gromacs and returns the exit code from
+    the manager.
+The %main() method also catches all exceptions, and if one is caught, prints an
+error message and terminates the program cleanly.
+
+Command line manager
+====================
+
+The core of the wrapper binary is the gmx::CommandLineModuleManager::run()
+method.  This method:
+ 1. Checks whether the binary is invoked through a symlink.  If it is, it
+    searches the registered modules for names matching the name of the symlink
+    (with certain prefixes in the symlink name ignored).  If a match is found,
+    it continues as if the command was invoked as `gmx` _module_ `...`, where
+    _module_ is the name of the found module and `...` are the rest of the
+    arguments.
+ 2. Parses the command line arguments before the module name as arguments to
+    the wrapper binary.  Some arguments such as `-h` and `-version` cause rest
+    of the command (the module name and all that follows) to be ignored.
+ 3. If a module is specified, also checks the command line arguments after the
+    module name for the options understood by the wrapper binary, such as `-h`
+    and `-version` (see below for details of how `-h` works).  Any such options
+    are handled by the manager and removed from the command line for further
+    processing.
+ 4. Print the startup header (contents of which can be controlled by the
+    command line options).
+ 5. If a command line option requests termination after the startup header
+    (such as `-version`), return.
+ 6. Passes control to the selected module.  If there is no module specified,
+    the help module is invoked (see below).
+ 7. Print a quote at the end, and return the exit code from the module.
+
+Command line help
+-----------------
+
+To handle the `gmx help ...` command, as well as for `gmx -h` and for
+`gmx` _module_ `-h`, the command line manager internally creates a module that
+handles the `help` command.  All command lines containing the `-h`, as well as
+invocation of `gmx` without any arguments, are translated to corresponding
+`gmx help` commands.  For example, `gmx` _module_ `-h` is handled exactly like
+`gmx help` _module_.  Note that if `-h` is specified for a module, the command
+line manager throws away all the other arguments before passing control to the
+module.
+
+After the above translations, the internal help module handles all the help
+output.  All the help is organized into a hierarchy of gmx::HelpTopicInterface
+instances.  The help module internally creates a root help topic that is
+printed with `gmx help`.  If there are additional words after the `gmx help`
+command, then those are taken to specify the topic to show in the hierarchy.
+
+gmx::CommandLineModuleManager internally creates a help topic for each added
+module.  These topics are shown when `gmx help` _module_ is invoked.
+They forward the request to the actual module (to
+gmx::CommandLineModuleInterface::writeHelp()).
+
+In addition to the topics created internally, gmx::CommandLineModuleManager
+provides methods to add additional help topics.  Currently, this is used to
+expose some reference material for the selections (the same content that is
+accessible using `help` in the selection prompt).
+
+Help export for other formats
+-----------------------------
+
+The build system provides two targets, `make man` and `make html`, to generate
+man pages and online HTML help for the commands.  These targets are run
+automatically as part of `make` if `GMX_BUILD_HELP=ON` is set in CMake.
+Otherwise, they can be run manually.  Internally, these execute
+`gmx help -export` _format_, which triggers special handling in the internal
+help module.
+
+If this option is set, the help module loops through all the modules in the
+binary, writing help for each into a separate file.  The help module writes
+common headers and footers, and asks the actual module to write the
+module-specific content (with gmx::CommandLineModuleInterface::writeHelp(),
+using a different help context than for console output).
+
+Additionally, a list of all the modules is generated (`gromacs.7` for man
+pages, and alphabetical and by-topic lists for the HTML pages).
+
+Part of the functionality depends on template files and other data files that
+the help module reads from `share/man/` and `share/html/` and uses to generate
+its output.
+
+Part of the HTML help is stored as partial HTML files under `share/html/`.
+To produce the full HTML pages, the `gmx help -export html` command creates
+`header.html` from a `header.html.in` template file.  This file is used by a
+separate CMake script that is run by `make html` to add headers and footers to
+these partial HTML files.
+The final HTML help is produced in `share/html/final/`.
+
+Handling C %main() functions
+----------------------------
+
+Many pre-5.0 modules are still implemented as a function with a C %main()
+signature.  All these binaries call parse_common_args() as more or less the
+first thing in their processing.  In order to implement the above approach, the
+module manager internally creates a command line module for these (in
+gmx::CommandLineModuleManager::addModuleCMain()).  The created module
+collaborates with parse_common_args() to achieve the same functionality as for
+the new C++ modules.
+
+Running the module simply executes the provided %main() method.
+Help writing is more complex, as it requires the help context to be passed from
+the module to parse_common_args().  This is handled using a global instance of
+the context (see gmx::GlobalCommandLineHelpContext).  This context is set in
+the module, and if parse_common_args() detects it, it prints out the help and
+returns `false` to indicate to the caller that it should immediately return.
index 017cac44bd0690b1ee8f202eb21818a5ecc1303a..d29ba2668f63a35b2bae5a2cd1d9d17e67ba27c5 100644 (file)
@@ -54,6 +54,7 @@
  *    provides the functionality to implement the `gmx` wrapper binary, as well
  *    as command line options common to all \Gromacs programs (such as
  *    `-version`).
+ *    This is described in more detail at \ref page_wrapperbinary.
  *    \endif
  *
  *  - Helper classes for particular command line tasks:
index 785667e1663ab12d73dc37b565440581be8b9f89..900958df6759e201f522b0d109e85c0fb53e8411 100644 (file)
  * To help us fund GROMACS development, we humbly ask that you cite
  * the research papers on the package. Check out http://www.gromacs.org.
  */
-/*! \file
+/*! \libinternal \file
  * \brief
  * Declares gmx::CommandLineModuleManager.
  *
  * \author Teemu Murtola <teemu.murtola@gmail.com>
- * \inpublicapi
+ * \inlibraryapi
  * \ingroup module_commandline
  */
 #ifndef GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
@@ -55,11 +55,14 @@ class CommandLineModuleGroupData;
 class CommandLineModuleInterface;
 class CommandLineProgramContext;
 
+//! \addtogroup module_commandline
+//! \{
+
 //! Smart pointer type for managing a CommandLineModuleInterface.
 typedef gmx_unique_ptr<CommandLineModuleInterface>::type
     CommandLineModulePointer;
 
-/*! \brief
+/*! \libinternal \brief
  * Implements a wrapper command-line interface for multiple modules.
  *
  * Typical usage:
@@ -83,8 +86,8 @@ typedef gmx_unique_ptr<CommandLineModuleInterface>::type
    }
  * \endcode
  *
- * \inpublicapi
- * \ingroup module_commandline
+ * \see page_wrapperbinary
+ * \inlibraryapi
  */
 class CommandLineModuleManager
 {
@@ -301,7 +304,7 @@ class CommandLineModuleManager
         PrivateImplPointer<Impl> impl_;
 };
 
-/*! \brief
+/*! \libinternal \brief
  * Handle to add content to a group added with
  * CommandLineModuleManager::addModuleGroup().
  *
@@ -310,8 +313,7 @@ class CommandLineModuleManager
  * point to the same group.  The actual state of the group is maintained in an
  * internal implementation class.
  *
- * \inpublicapi
- * \ingroup module_commandline
+ * \inlibraryapi
  */
 class CommandLineModuleGroup
 {
@@ -353,6 +355,8 @@ class CommandLineModuleGroup
         Impl                     *impl_;
 };
 
+//! \}
+
 } // namespace gmx
 
 #endif
diff --git a/src/gromacs/onlinehelp.h b/src/gromacs/onlinehelp.h
new file mode 100644 (file)
index 0000000..9a5caf6
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \defgroup module_onlinehelp Help Formatting for Online Help (onlinehelp)
+ * \ingroup group_utilitymodules
+ * \brief
+ * Provides functionality for formatting help text for console and other
+ * formats.
+ *
+ * This module provides helper functions and classes for formatting console
+ * help, as well as man pages and HTML help from the source code.  It should
+ * not be necessary to call any methods in this module outside the \Gromacs
+ * library.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ */
+/*! \file
+ * \brief
+ * Public API convenience header for help formatting.
+ *
+ * This module does not provide any classes that are intended to be used
+ * outside the library.  It only contains some type declarations that are
+ * necessary for implementation reasons in other public API headers.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_onlinehelp
+ */
+#ifndef GMX_ONLINEHELP_H
+#define GMX_ONLINEHELP_H
+
+#include "onlinehelp/helptopicinterface.h"
+
+#endif
index 1071f501521e717e4942c25695d31fc78efa62ea..1c6926369fdceb45174d2515e307494f35e37a2e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -37,7 +37,7 @@
  * Declares gmx::HelpTopicInterface.
  *
  * \author Teemu Murtola <teemu.murtola@gmail.com>
- * \inpublicapi
+ * \inlibraryapi
  * \ingroup module_onlinehelp
  */
 #ifndef GMX_ONLINEHELP_HELPTOPICINTERFACE_H