Gromacs
2019
|
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.
The main() method for the wrapper binary is implemented in src/programs/gmx.cpp
. This is a very simple code that does these basic tasks:
src/programs/legacymodules.cpp
. New C++ tools are added from src/gromacs/trajectoryanalysis/modules.cpp
.All modules within the wrapper binary are implemented as classes that implement the gmx::ICommandLineModule interface. There is generally some helper class in between:
The core of the wrapper binary is the gmx::CommandLineModuleManager::run() method. This method:
-h
and -version
cause rest of the command (the module name and all that follows) to be ignored.-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.-version
), return.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::IHelpTopic 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::ICommandLineModule::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).
The build system provides a target, make sphinx-programs
, that generates reStructuredText help for the commands, which in turn is used to generate man and HTML help. Internally, this executes gmx help -export rst
, which triggers special handling in the internal help module. See documentation for special targets in the build system for details of which targets to use for generating the documentation..
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::ICommandLineModule::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).
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.