Merge release-4-6 (commit 'Ic142a690')
[alexxy/gromacs.git] / src / gromacs / commandline / cmdlinemodulemanager.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \file
32  * \brief
33  * Declares gmx::CommandLineModuleManager.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \inpublicapi
37  * \ingroup module_commandline
38  */
39 #ifndef GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
40 #define GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
41
42 #include "../utility/common.h"
43 #include "../utility/uniqueptr.h"
44
45 namespace gmx
46 {
47
48 class CommandLineModuleInterface;
49 class ProgramInfo;
50
51 //! Smart pointer type for managing a CommandLineModuleInterface.
52 typedef gmx_unique_ptr<CommandLineModuleInterface>::type
53         CommandLineModulePointer;
54
55 namespace internal
56 {
57 class CommandLineHelpModule;
58 }
59
60 /*! \brief
61  * Implements a wrapper command-line interface for multiple modules.
62  *
63  * Typical usage:
64  * \code
65 int
66 main(int argc, char *argv[])
67 {
68     const gmx::ProgramInfo &programInfo =
69         gmx::ProgramInfo::init("g_ana", argc, argv);
70     CopyRight(stderr, argv[0]);
71     try
72     {
73         gmx::CommandLineModuleManager manager(programInfo);
74         // <register all necessary modules>
75         return manager.run(argc, argv);
76     }
77     catch (const std::exception &ex)
78     {
79         fprintf(stderr, "%s", gmx::formatErrorMessage(ex).c_str());
80         return 1;
81     }
82 }
83  * \endcode
84  *
85  * \inpublicapi
86  * \ingroup module_commandline
87  */
88 class CommandLineModuleManager
89 {
90     public:
91         /*! \brief
92          * Initializes a command-line module manager.
93          *
94          * \param[in] programInfo  Program information for the running binary.
95          * \throws    std::bad_alloc if out of memory.
96          *
97          * The binary name is used to detect when the binary is run through a
98          * symlink, and automatically invoke a matching module in such a case.
99          */
100         explicit CommandLineModuleManager(const ProgramInfo &programInfo);
101         ~CommandLineModuleManager();
102
103         /*! \brief
104          * Adds a given module to this manager.
105          *
106          * \param   module  Module to add.
107          * \throws  std::bad_alloc if out of memory.
108          *
109          * The manager takes ownership of the object.
110          *
111          * This method is public mostly for testing purposes; for typical uses,
112          * registerModule() is a more convenient way of adding modules.
113          *
114          * \see registerModule()
115          */
116         void addModule(CommandLineModulePointer module);
117         /*! \brief
118          * Registers a module of a certain type to this manager.
119          *
120          * \tparam  Module  Type of module to register.
121          * \throws  std::bad_alloc if out of memory.
122          *
123          * \p Module must be default-constructible and implement
124          * CommandLineModuleInterface.
125          *
126          * This method is provided as a convenient alternative to addModule()
127          * for cases where each module is implemented by a different type
128          * (which should be the case for typical situations outside unit
129          * tests).
130          */
131         template <class Module>
132         void registerModule()
133         {
134             addModule(CommandLineModulePointer(new Module));
135         }
136
137         /*! \brief
138          * Runs a module based on given command line.
139          *
140          * \param[in] argc  Number of elements in \p argv.
141          * \param[in] argv  Command-line arguments.
142          * \throws   unspecified  Throws any exception that the selected module
143          *      throws.
144          * \returns  Exit code for the program.
145          * \retval   0 on successful termination.
146          * \retval   2 if no module is specified, or if the module is not found.
147          *
148          * Runs the module whose name matches \p argv[1].
149          */
150         int run(int argc, char *argv[]);
151
152     private:
153         class Impl;
154
155         PrivateImplPointer<Impl> impl_;
156
157         /*! \brief
158          * Needed to access information about registered modules etc.
159          */
160         friend class internal::CommandLineHelpModule;
161 };
162
163 } // namespace gmx
164
165 #endif