00a3699ddf820f95c7faefa333f9511196ee8f0e
[alexxy/gromacs.git] / src / gromacs / commandline / cmdlineprogramcontext.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014,2015,2018 by the GROMACS development team.
5  * Copyright (c) 2019,2020, by the GROMACS development team, led by
6  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7  * and including many others, as listed in the AUTHORS file in the
8  * top-level source directory and at http://www.gromacs.org.
9  *
10  * GROMACS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1
13  * of the License, or (at your option) any later version.
14  *
15  * GROMACS is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with GROMACS; if not, see
22  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24  *
25  * If you want to redistribute modifications to GROMACS, please
26  * consider that scientific software is very special. Version
27  * control is crucial - bugs must be traceable. We will be happy to
28  * consider code for inclusion in the official distribution, but
29  * derived work must not be called official GROMACS. Details are found
30  * in the README & COPYING files - if they are missing, get the
31  * official version at http://www.gromacs.org.
32  *
33  * To help us fund GROMACS development, we humbly ask that you cite
34  * the research papers on the package. Check out http://www.gromacs.org.
35  */
36 /*! \file
37  * \brief
38  * Declares gmx::CommandLineProgramContext.
39  *
40  * This header is installed to support cmdlineinit.h because some compilers
41  * don't allow returning a reference to an incomplete type from a function.
42  * It should not be necessary to use gmx::CommandLineProgramContext outside the
43  * \Gromacs library.
44  *
45  * \author Teemu Murtola <teemu.murtola@gmail.com>
46  * \inlibraryapi
47  * \ingroup module_commandline
48  */
49 #ifndef GMX_COMMANDLINE_CMDLINEPROGRAMCONTEXT_H
50 #define GMX_COMMANDLINE_CMDLINEPROGRAMCONTEXT_H
51
52 #include <memory>
53 #include <string>
54 #include <vector>
55
56 #include "gromacs/utility/classhelpers.h"
57 #include "gromacs/utility/programcontext.h"
58
59 namespace gmx
60 {
61
62 //! \addtogroup module_commandline
63 //! \{
64
65 /*! \libinternal \brief
66  * Allows customization of the way various directories are found by
67  * CommandLineProgramContext.
68  *
69  * For the CommandLineProgramContext constructors that do not take this
70  * interface as a parameter, a default implementation is used that forwards
71  * the calls to the corresponding methods in gmx::Path.
72  *
73  * \inlibraryapi
74  */
75 class IExecutableEnvironment
76 {
77 public:
78     virtual ~IExecutableEnvironment() {}
79
80     /*! \brief
81      * Returns the working directory when the program was launched.
82      */
83     virtual std::string getWorkingDirectory() const = 0;
84     /*! \brief
85      * Returns list of paths where executables are searched for.
86      *
87      * The returned list should be in priority order.  An empty string in
88      * the returned list corresponds to getWorkindDirectory().
89      */
90     virtual std::vector<std::string> getExecutablePaths() const = 0;
91 };
92
93 //! Shorthand for a smart pointer to IExecutableEnvironment.
94 typedef std::unique_ptr<IExecutableEnvironment> ExecutableEnvironmentPointer;
95
96 /*! \libinternal \brief
97  * Program context implementation for command line programs.
98  *
99  * Constructors are provided mostly for unit testing purposes; in normal usage,
100  * a single CommandLineProgramContext object is constructed with
101  * initForCommandLine() in the beginning of the program.
102  * The returned object can be explicitly passed to other methods, or accessed
103  * through getProgramContext().
104  *
105  * Unless explicitly noted otherwise, methods in this class may throw
106  * std::bad_alloc on out-of-memory conditions, but do not throw other
107  * exceptions.
108  *
109  * \inlibraryapi
110  */
111 class CommandLineProgramContext : public IProgramContext
112 {
113 public:
114     /*! \brief
115      * Constructs an empty context object.
116      *
117      * All methods in the constructed object return dummy values.
118      */
119     CommandLineProgramContext();
120     /*! \brief
121      * Initializes a program context object with binary name only.
122      *
123      * \param[in] binaryName  Name of the binary.
124      *
125      * This is needed for unit testing purposes.
126      * The constructed object works as if the command line consisted of
127      * only of the binary name.
128      */
129     explicit CommandLineProgramContext(const char* binaryName);
130     /*! \brief
131      * Initializes a program context object based on command line.
132      *
133      * \param[in] argc  argc value passed to main().
134      * \param[in] argv  argv array passed to main().
135      */
136     CommandLineProgramContext(int argc, const char* const argv[]);
137     /*! \brief
138      * Initializes a program context object based on command line.
139      *
140      * \param[in] argc  argc value passed to main().
141      * \param[in] argv  argv array passed to main().
142      * \param[in] env   Customizes the way the binary name is handled.
143      *
144      * This overload allows one to customize the way the binary is located
145      * by providing a custom IExecutableEnvironment implementation.
146      * This is mainly useful for testing purposes to make it possible to
147      * test different paths without setting environment variables, changing
148      * the working directory or doing other process-wide operations.
149      * It may also be useful for making Gromacs behave better when linked
150      * into a non-Gromacs executable (with possible extensions in
151      * IExecutableEnvironment).
152      */
153     CommandLineProgramContext(int argc, const char* const argv[], ExecutableEnvironmentPointer env);
154     ~CommandLineProgramContext() override;
155
156     /*! \brief
157      * Sets a display name for the binary.
158      *
159      * \throws std::bad_alloc if out of memory.
160      *
161      * This is used with the wrapper binary to add the name of the invoked
162      * module to the name of the binary shown.
163      *
164      * It is not threadsafe if there are concurrent calls to displayName()
165      * before this method has returned.  Thread safety is not required for
166      * the normal initialization sequence of command line programs; it is
167      * called in the wrapper binary before the control passes to the actual
168      * module which may create threads.
169      */
170     void setDisplayName(const std::string& name);
171
172     /*! \brief
173      * Returns the name of the binary as it was invoked without any path.
174      *
175      * Does not throw.
176      */
177     const char* programName() const override;
178     /*! \brief
179      * Returns a display name of the current module.
180      *
181      * The returned value equals programName(), unless a separate display
182      * name has been set with setDisplayName().
183      *
184      * Does not throw.
185      */
186     const char* displayName() const override;
187     /*! \brief
188      * Returns the full path of the running binary.
189      *
190      * \throws std::bad_alloc if out of memory.
191      * \throws tMPI::system_error on thread synchronization errors.
192      *
193      * Returns argv[0] if there was an error in finding the absolute path.
194      */
195     const char* fullBinaryPath() const override;
196     /*! \brief
197      * Returns the installation prefix (for finding \Gromacs data files).
198      *
199      * \throws std::bad_alloc if out of memory.
200      * \throws tMPI::system_error on thread synchronization errors.
201      *
202      * Returns a hardcoded path set during configuration time if there is
203      * an error in finding the library data files.
204      */
205     InstallationPrefixInfo installationPrefix() const override;
206     /*! \brief
207      * Returns the full command line used to invoke the binary.
208      *
209      * Does not throw.
210      */
211     const char* commandLine() const override;
212
213 private:
214     class Impl;
215
216     PrivateImplPointer<Impl> impl_;
217 };
218
219 } // namespace gmx
220
221 #endif