Change naming convention for C++ interfaces
[alexxy/gromacs.git] / docs / doxygen / lib / wrapperbinary.md
1 Wrapper binary implementation {#page_wrapperbinary}
2 =============================
3
4 This page mainly describes the implementation of the `gmx` wrapper binary.
5 Many of the details are not visible to most of the code, but this documentation
6 is included as part of the library API documentation to make it easier to
7 understand the overall implementation without reading extensive documentation.
8
9 %main() implementation
10 ======================
11
12 The %main() method for the wrapper binary is implemented in
13 `src/programs/gmx.cpp`.  This is a very simple code that does these basic
14 tasks:
15  1. Initializes \Gromacs using gmx::initForCommandLine()
16     (see \ref page_usinglibrary).
17  2. Creates a gmx::CommandLineModuleManager instance for the wrapper binary.
18  3. Calls various methods to add modules to the manager and initialize it
19     otherwise.  Many of the pre-5.0 binaries are added from
20     `src/programs/legacymodules.cpp`.  New C++ tools are added from
21     `src/gromacs/trajectoryanalysis/modules.cpp`.
22  4. Passes control to the manager (see below).
23  5. On successful return, deinitializes \Gromacs and returns the exit code from
24     the manager.
25 The %main() method also catches all exceptions, and if one is caught, prints an
26 error message and terminates the program cleanly.
27
28 Command line modules
29 ====================
30
31 All modules within the wrapper binary are implemented as classes that implement
32 the gmx::ICommandLineModule interface.  There is generally some helper
33 class in between:
34  * General C++ modules typically use gmx::Options for their command-line
35    handling.  Instead of each module implementing parsing and help separately
36    with identical code, they implement gmx::ICommandLineOptionsModule
37    instead.  The framework then provides a bridge class that contains the
38    common code and wraps gmx::ICommandLineOptionsModule into a
39    gmx::ICommandLineModule.
40  * For C++ trajectory analysis modules, there is a general implementation for
41    running the gmx::TrajectoryAnalysisModule subclasses in cmdlinerunner.cpp.
42  * For old C-style %main() functions, see \ref section_wrapperbinary_cmain.
43
44 Command line manager {#section_wrapperbinary_manager}
45 ====================
46
47 The core of the wrapper binary is the gmx::CommandLineModuleManager::run()
48 method.  This method:
49  1. Parses the command line arguments before the module name as arguments to
50     the wrapper binary.  Some arguments such as `-h` and `-version` cause rest
51     of the command (the module name and all that follows) to be ignored.
52  2. If a module is specified, also checks the command line arguments after the
53     module name for the options understood by the wrapper binary, such as `-h`
54     and `-version` (see below for details of how `-h` works).  Any such options
55     are handled by the manager and removed from the command line for further
56     processing.
57  3. Print the startup header (contents of which can be controlled by the
58     command line options).
59  4. If a command line option requests termination after the startup header
60     (such as `-version`), return.
61  5. Passes control to the selected module.  If there is no module specified,
62     the help module is invoked (see below).
63  6. Print a quote at the end, and return the exit code from the module.
64
65 Command line help
66 -----------------
67
68 To handle the `gmx help ...` command, as well as for `gmx -h` and for
69 `gmx` _module_ `-h`, the command line manager internally creates a module that
70 handles the `help` command.  All command lines containing the `-h`, as well as
71 invocation of `gmx` without any arguments, are translated to corresponding
72 `gmx help` commands.  For example, `gmx` _module_ `-h` is handled exactly like
73 `gmx help` _module_.  Note that if `-h` is specified for a module, the command
74 line manager throws away all the other arguments before passing control to the
75 module.
76
77 After the above translations, the internal help module handles all the help
78 output.  All the help is organized into a hierarchy of gmx::IHelpTopic
79 instances.  The help module internally creates a root help topic that is
80 printed with `gmx help`.  If there are additional words after the `gmx help`
81 command, then those are taken to specify the topic to show in the hierarchy.
82
83 gmx::CommandLineModuleManager internally creates a help topic for each added
84 module.  These topics are shown when `gmx help` _module_ is invoked.
85 They forward the request to the actual module (to
86 gmx::ICommandLineModule::writeHelp()).
87
88 In addition to the topics created internally, gmx::CommandLineModuleManager
89 provides methods to add additional help topics.  Currently, this is used to
90 expose some reference material for the selections (the same content that is
91 accessible using `help` in the selection prompt).
92
93 Help in other formats
94 ---------------------
95
96 The build system provides a target, `make sphinx-programs`, that generates
97 reStructuredText help for the commands, which in turn is used to generate man
98 and HTML help.  Internally, this executes `gmx help -export rst`, which
99 triggers special handling in the internal help module.
100 See documentation for
101 \linktodevmanual{build-system,special targets in the build system} for details
102 of which targets to use for generating the documentation..
103
104 If this option is set, the help module loops through all the modules in the
105 binary, writing help for each into a separate file.  The help module writes
106 common headers and footers, and asks the actual module to write the
107 module-specific content (with gmx::ICommandLineModule::writeHelp(),
108 using a different help context than for console output).
109
110 Additionally, a list of all the modules is generated (`gromacs.7` for man
111 pages, and alphabetical and by-topic lists for the HTML pages).
112
113 Handling C %main() functions {#section_wrapperbinary_cmain}
114 ----------------------------
115
116 Many pre-5.0 modules are still implemented as a function with a C %main()
117 signature.  All these binaries call parse_common_args() as more or less the
118 first thing in their processing.  In order to implement the above approach, the
119 module manager internally creates a command line module for these (in
120 gmx::CommandLineModuleManager::addModuleCMain()).  The created module
121 collaborates with parse_common_args() to achieve the same functionality as for
122 the new C++ modules.
123
124 Running the module simply executes the provided %main() method.
125 Help writing is more complex, as it requires the help context to be passed from
126 the module to parse_common_args().  This is handled using a global instance of
127 the context (see gmx::GlobalCommandLineHelpContext).  This context is set in
128 the module, and if parse_common_args() detects it, it prints out the help and
129 returns `false` to indicate to the caller that it should immediately return.