Merge release-4-6 into master
[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 "../onlinehelp/helptopicinterface.h"
43 #include "../utility/common.h"
44 #include "../utility/uniqueptr.h"
45
46 namespace gmx
47 {
48
49 class CommandLineModuleInterface;
50 class ProgramInfo;
51
52 //! Smart pointer type for managing a CommandLineModuleInterface.
53 typedef gmx_unique_ptr<CommandLineModuleInterface>::type
54         CommandLineModulePointer;
55
56 /*! \brief
57  * Implements a wrapper command-line interface for multiple modules.
58  *
59  * Typical usage:
60  * \code
61 int
62 main(int argc, char *argv[])
63 {
64     const gmx::ProgramInfo &programInfo =
65         gmx::ProgramInfo::init("g_ana", argc, argv);
66     CopyRight(stderr, argv[0]);
67     try
68     {
69         gmx::CommandLineModuleManager manager(programInfo);
70         // <register all necessary modules>
71         return manager.run(argc, argv);
72     }
73     catch (const std::exception &ex)
74     {
75         gmx::printFatalErrorMessage(stderr, ex);
76         return 1;
77     }
78 }
79  * \endcode
80  *
81  * \inpublicapi
82  * \ingroup module_commandline
83  */
84 class CommandLineModuleManager
85 {
86     public:
87         /*! \brief
88          * Initializes a command-line module manager.
89          *
90          * \param[in] programInfo  Program information for the running binary.
91          * \throws    std::bad_alloc if out of memory.
92          *
93          * The binary name is used to detect when the binary is run through a
94          * symlink, and automatically invoke a matching module in such a case.
95          */
96         explicit CommandLineModuleManager(const ProgramInfo &programInfo);
97         ~CommandLineModuleManager();
98
99         /*! \brief
100          * Adds a given module to this manager.
101          *
102          * \param   module  Module to add.
103          * \throws  std::bad_alloc if out of memory.
104          *
105          * The manager takes ownership of the object.
106          *
107          * This method is public mostly for testing purposes; for typical uses,
108          * registerModule() is a more convenient way of adding modules.
109          *
110          * \see registerModule()
111          */
112         void addModule(CommandLineModulePointer module);
113         /*! \brief
114          * Registers a module of a certain type to this manager.
115          *
116          * \tparam  Module  Type of module to register.
117          * \throws  std::bad_alloc if out of memory.
118          *
119          * \p Module must be default-constructible and implement
120          * CommandLineModuleInterface.
121          *
122          * This method is provided as a convenient alternative to addModule()
123          * for cases where each module is implemented by a different type
124          * (which should be the case for typical situations outside unit
125          * tests).
126          */
127         template <class Module>
128         void registerModule()
129         {
130             addModule(CommandLineModulePointer(new Module));
131         }
132
133         /*! \brief
134          * Make given help topic available through the manager's help module.
135          *
136          * \param[in]  topic  Help topic to add.
137          * \throws     std::bad_alloc if out of memory.
138          *
139          * The manager takes ownership of the help topic.
140          */
141         void addHelpTopic(HelpTopicPointer topic);
142
143         /*! \brief
144          * Runs a module based on given command line.
145          *
146          * \param[in] argc  Number of elements in \p argv.
147          * \param[in] argv  Command-line arguments.
148          * \throws   unspecified  Throws any exception that the selected module
149          *      throws.
150          * \returns  Exit code for the program.
151          * \retval   0 on successful termination.
152          * \retval   2 if no module is specified, or if the module is not found.
153          *
154          * Runs the module whose name matches \p argv[1].
155          */
156         int run(int argc, char *argv[]);
157
158     private:
159         class Impl;
160
161         PrivateImplPointer<Impl> impl_;
162 };
163
164 } // namespace gmx
165
166 #endif