Clean up cmake build host detection
[gromacs.git] / src / gromacs / utility / datafilefinder.h
blob488c6c65de10a93c3dafb2ec24523a2b2dea0618
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2014,2015, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \file
36 * \brief
37 * Declares gmx::DataFileFinder and related classes.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \inpublicapi
41 * \ingroup module_utility
43 #ifndef GMX_UTILITY_LIBFILEFINDER_H
44 #define GMX_UTILITY_LIBFILEFINDER_H
46 #include <cstdio>
48 #include <string>
49 #include <vector>
51 #include "gromacs/utility/classhelpers.h"
53 namespace gmx
56 class DataFileFinder;
58 /*! \brief
59 * Search parameters for DataFileFinder.
61 * This class implements a named parameter idiom for DataFileFinder::findFile()
62 * and DataFileFinder::openFile() to support an easily readable and
63 * customizable way of searching data files.
65 * By default, the search first considers the current directory, followed by
66 * specified and default data directories, and an exception is thrown if the
67 * file could not be found.
68 * To skip searching in the current directory, use includeCurrentDir().
70 * Methods in this class do not throw.
72 * \inpublicapi
73 * \ingroup module_utility
75 class DataFileOptions
77 public:
78 /*! \brief
79 * Constructs default options for searching for a file with the
80 * specified name.
82 * \param[in] filename File name to search for.
84 * This constructor is not explicit to allow passing a simple string to
85 * DataFileFinder methods to search for the string with the default
86 * parameters.
88 DataFileOptions(const char *filename)
89 : filename_(filename), bCurrentDir_(true), bThrow_(true)
92 //! \copydoc DataFileOptions(const char *)
93 DataFileOptions(const std::string &filename)
94 : filename_(filename.c_str()), bCurrentDir_(true), bThrow_(true)
98 //! Sets whether to search in the current (working) directory.
99 DataFileOptions &includeCurrentDir(bool bInclude)
101 bCurrentDir_ = bInclude;
102 return *this;
104 //! Sets whether an exception is thrown if the file could not be found.
105 DataFileOptions &throwIfNotFound(bool bThrow)
107 bThrow_ = bThrow;
108 return *this;
111 private:
112 const char *filename_;
113 bool bCurrentDir_;
114 bool bThrow_;
116 /*! \brief
117 * Needed to access the members without otherwise unnecessary accessors.
119 friend class DataFileFinder;
122 /*! \brief
123 * Information about a data file found by DataFileFinder::enumerateFiles().
125 * \inpublicapi
126 * \ingroup module_utility
128 struct DataFileInfo
130 //! Initializes the structure with given values.
131 DataFileInfo(const std::string &dir, const std::string &name, bool bDefault)
132 : dir(dir), name(name), bFromDefaultDir(bDefault)
136 /*! \brief
137 * Directory from which the file was found.
139 * If the file was found from the current directory, this will be `"."`.
140 * In other cases, this will be a full path (except if the user-provided
141 * search path contains relative paths).
143 std::string dir;
144 /*! \brief
145 * Name of the file without any directory name.
147 std::string name;
148 /*! \brief
149 * Whether the file was found from the default directory.
151 * If `true`, the file was found from the default installation data
152 * directory, not from the current directory or any user-provided (through
153 * DataFileFinder::setSearchPathFromEnv()) location.
154 * \todo
155 * Consider replacing with an enum that identifies the source (current dir,
156 * GMXLIB, default).
158 bool bFromDefaultDir;
161 /*! \brief
162 * Searches data files from a set of paths.
164 * \inpublicapi
165 * \ingroup module_utility
167 class DataFileFinder
169 public:
170 /*! \brief
171 * Constructs a default data file finder.
173 * The constructed finder searches only in the directory specified by
174 * the global program context (see IProgramContext), and
175 * optionally in the current directory.
177 * Does not throw.
179 DataFileFinder();
180 ~DataFileFinder();
182 /*! \brief
183 * Adds search path from an environment variable.
185 * \param[in] envVarName Name of the environment variable to use.
186 * \throws std::bad_alloc if out of memory.
188 * If the specified environment variable is set, it is interpreted like
189 * a `PATH` environment variable on the platform (split at appropriate
190 * separators), and each path found is added to the search path this
191 * finder searches. The added paths take precedence over the default
192 * directory specified by the global program context, but the current
193 * directory is searched first.
195 void setSearchPathFromEnv(const char *envVarName);
197 /*! \brief
198 * Opens a data file if found.
200 * \param[in] options Identifies the file to be searched for.
201 * \returns The opened file handle, or `NULL` if the file could not be
202 * found and exceptions were turned off.
203 * \throws std::bad_alloc if out of memory.
204 * \throws FileIOError if
205 * - no such file can be found, and \p options specifies that an
206 * exception should be thrown, or
207 * - there is an error opening the file (note that a file is skipped
208 * during the search if the user does not have rights to open the
209 * file at all).
211 * See findFile() for more details.
213 FILE *openFile(const DataFileOptions &options) const;
214 /*! \brief
215 * Finds a full path to a data file if found.
217 * \param[in] options Identifies the file to be searched for.
218 * \returns Full path to the data file, or an empty string if the file
219 * could not be found and exceptions were turned off.
220 * \throws std::bad_alloc if out of memory.
221 * \throws FileIOError if no such file can be found, and \p options
222 * specifies that an exception should be thrown.
224 * Searches for a data file in the search paths configured for the
225 * finder, as well as in the current directory if so required.
226 * Returns the full path to the first file found.
228 std::string findFile(const DataFileOptions &options) const;
229 /*! \brief
230 * Enumerates files in the data directories.
232 * \param[in] options Idenfies files to be searched for.
233 * \returns Information about each found file.
234 * \throws std::bad_alloc if out of memory.
235 * \throws FileIOError if no such file can be found, and \p options
236 * specifies that an exception should be thrown.
238 * Enumerates all files in the data directories that have the
239 * extension/suffix specified by the file name in \p options.
240 * Unlike findFile() and openFile(), this only works on files that are
241 * in the actual data directories, not for any entry within
242 * subdirectories of those.
243 * See DataFileInfo for details on what is returned for each found
244 * file.
245 * Files from the same directory will be returned as a continuous block
246 * in the returned vector.
248 std::vector<DataFileInfo> enumerateFiles(const DataFileOptions &options) const;
250 private:
251 class Impl;
253 PrivateImplPointer<Impl> impl_;
256 } // namespace gmx
258 #endif