Generic handling for multiple cmd-line modules.
[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
50 //! Smart pointer type for managing a CommandLineModuleInterface.
51 typedef gmx_unique_ptr<CommandLineModuleInterface>::type
52         CommandLineModulePointer;
53
54 /*! \brief
55  * Implements a wrapper command-line interface for multiple modules.
56  *
57  * Typical usage:
58  * \code
59 int
60 main(int argc, char *argv[])
61 {
62     CopyRight(stderr, argv[0]);
63     try
64     {
65         gmx::CommandLineModuleManager manager;
66         // <register all necessary modules>
67         return manager.run(argc, argv);
68     }
69     catch (const std::exception &ex)
70     {
71         fprintf(stderr, "%s", gmx::formatErrorMessage(ex).c_str());
72         return 1;
73     }
74 }
75  * \endcode
76  *
77  * \inpublicapi
78  * \ingroup module_commandline
79  */
80 class CommandLineModuleManager
81 {
82     public:
83         CommandLineModuleManager();
84         ~CommandLineModuleManager();
85
86         /*! \brief
87          * Adds a given module to this manager.
88          *
89          * \param   module  Module to add.
90          * \throws  std::bad_alloc if out of memory.
91          *
92          * The manager takes ownership of the object.
93          *
94          * This method is public mostly for testing purposes; for typical uses,
95          * registerModule() is a more convenient way of adding modules.
96          *
97          * \see registerModule()
98          */
99         void addModule(CommandLineModulePointer module);
100         /*! \brief
101          * Registers a module of a certain type to this manager.
102          *
103          * \tparam  Module  Type of module to register.
104          * \throws  std::bad_alloc if out of memory.
105          *
106          * \p Module must be default-constructible and implement
107          * CommandLineModuleInterface.
108          *
109          * This method is provided as a convenient alternative to addModule()
110          * for cases where each module is implemented by a different type
111          * (which should be the case for typical situations outside unit
112          * tests).
113          */
114         template <class Module>
115         void registerModule()
116         {
117             addModule(CommandLineModulePointer(new Module));
118         }
119
120         /*! \brief
121          * Runs a module based on given command line.
122          *
123          * \param[in] argc  Number of elements in \p argv.
124          * \param[in] argv  Command-line arguments.
125          * \throws   unspecified  Throws any exception that the selected module
126          *      throws.
127          * \returns  Exit code for the program.
128          * \retval   0 on successful termination.
129          * \retval   2 if no module is specified, or if the module is not found.
130          *
131          * Runs the module whose name matches \p argv[1].
132          */
133         int run(int argc, char *argv[]);
134
135     private:
136         class Impl;
137
138         PrivateImplPointer<Impl> impl_;
139 };
140
141 } // namespace gmx
142
143 #endif