Flow123d  release_3.0.0-965-gb0c8897
file_path.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file file_path.hh
15  * @brief
16  */
17 
18 #ifndef FILE_NAME_HH_
19 #define FILE_NAME_HH_
20 
21 #include <string>
22 #include "system/exceptions.hh"
23 
24 #include <boost/exception/info.hpp> // for error_info::~error_info<Tag, T>
25 #include <iosfwd> // for ostream
26 #include <map> // for map
27 #include <memory> // for shared_ptr
28 #include <vector> // for vector
29 
30 
31 using namespace std;
32 
33 
34 namespace boost {
35  namespace filesystem {
36  class path;
37 }}
38 
39 
40 
41 
42 /**
43  * @brief Dedicated class for storing path to input and output files.
44  *
45  * FilePath objects are constructed from given absolute or relative path to the file and its type (input or output).
46  * Before you create any instance of the class you have to call static method @p set_io_dirs to set:
47  * - working directory of the program (when it was started)
48  * - root input directory, i.e. directory of the main input file (given by -s parameter)
49  * - input directory, used to replace $INPUT_DIR$ placeholder (given by -i parameter)
50  * - output directory, where all output files should be placed (given by -o parameter)
51  *
52  */
53 
54 class FilePath {
55 public:
56 
57  /**
58  * Reporting failure when openning a file.
59  */
60  TYPEDEF_ERR_INFO( EI_Path, string);
61  TYPEDEF_ERR_INFO( EI_Address_String, string);
62  DECLARE_EXCEPTION( ExcFileOpen, << "Can not open file: " << EI_Path::qval << "\nAt input address: " << EI_Address_String::qval );
63  DECLARE_EXCEPTION( ExcAbsOutputPath, << "Can not set absolute path " << EI_Path::qval << " for an output file." );
64  DECLARE_EXCEPTION( ExcMkdirFail, << "Can not create directory: " << EI_Path::qval );
65 
66  /// Possible types of file.
67  enum FileType {
69  output_file
70  };
71 
72  /**
73  * Default constructor, necessary when using Input::Record::opt_val() to initialize a FilePath.
74  */
75  FilePath();
76 
77  /**
78  * Translates the given absolute or relative path to a file @p file_path depending on the file type @p ft.
79  *
80  * For input files:
81  * - For relative path prepend absolute path of the directory of the main input file (root directory).
82  * - Replace $INPUT_DIR$ place holder with the input directory given at command line.
83  *
84  * For output files:
85  * - Forbids absolute output paths.
86  * - For relative output path prepends it by the output directory given at the command line.
87  */
88  FilePath(string file_path, const FileType ft);
89 
90  /// Same as previous, but create path from vector of strings.
91  FilePath(vector<string> sub_paths, const FileType ft);
92 
93  /// Same as previous but implicitly use FileType::output_file
94  FilePath(string file_path);
95 
96  /**
97  * @brief Obsolete method for set input and output directories.
98  *
99  * Ensures consistency of unit tests.
100  *
101  * Set:
102  * - working directory (used only if the output directory is relative)
103  * - root directory (of the main input file)
104  * - input directory to replace $INPUT_DIR$ place holder
105  * - output directory used as prefix to the output files (relative output dirs are relative to the working directory)
106  */
107  static void set_io_dirs(const string working_dir, const string root, const string input, const string output);
108 
109  /**
110  * @brief Method for set input and output directories.
111  *
112  * Set:
113  * - root directory (of the main input file)
114  * - input directory to replace $INPUT_DIR$ place holder
115  * - output directory used as prefix to the output files (relative output dirs are relative to the working directory)
116  */
117  static void set_dirs(const string root, const string input, const string output);
118 
119  /**
120  * @brief Method for set input and output directories.
121  *
122  * Same as previous, but in first argument accepts full path of yaml file and returns filename of this yaml file.
123  *
124  * Set:
125  * - root directory (of the main yaml input file)
126  * - input directory to replace $INPUT_DIR$ place holder
127  * - output directory used as prefix to the output files (relative output dirs are relative to the working directory)
128  */
129  static string set_dirs_from_input(const string main_yaml, const string input, const string output);
130 
131  /**
132  * This class is implicitly convertible to string.
133  */
134  operator string() const;
135 
136  /*!
137  * @brief Add new item to place holder.
138  *
139  * Placeholder is extended by adding a single new item. The item can be used in the name of the input or output file name.
140  * Currently, the only supported placeholder is $INPUT_DIR$.
141  *
142  * @par Example usage:
143  * @code
144  * FilePath::add_placeholder_item("${SUBST_VAL}", "path/value");
145  * @endcode
146  *
147  * @param[in] key Key of new item.
148  * @param[in] value Value of new item.
149  */
150  static void add_placeholder(string key,string value);
151 
152  /**
153  * Return absolute path of actual working directory.
154  */
155  static const string get_absolute_working_dir();
156 
157  /// Equality comparison operators for FilePaths.
158  bool operator ==(const FilePath &other) const;
159 
160 
161  /**
162  * For an output filepath, the directory part (up to last separator) is
163  * extracted and all subdirectories are created if doesn't exist yet.
164  */
165  void create_output_dir();
166 
167  /**
168  * Return path to file.
169  */
170  string parent_path() const;
171 
172  /**
173  * Return name of file with extension.
174  */
175  string filename() const;
176 
177  /**
178  * Return name of file without extension.
179  */
180  string stem() const;
181 
182  /**
183  * Return extension of file.
184  */
185  string extension() const;
186 
187  /**
188  * Return path to file with filename without extension.
189  */
190  string cut_extension() const;
191 
192 
193  /**
194  * Open stream for this FilePath.
195  * Open mode is determined from the FilePath type.
196  */
197  template <class Stream>
198  void open_stream(Stream &stream) const;
199 
200  /**
201  * Return true if the FilePath is a file.
202  */
203  bool exists() const;
204 
205 private:
206  /**
207  * Create a directory, and check for exceptions.
208  */
209  static void create_dir(const boost::filesystem::path &dir);
210 
211  /**
212  * Substitutes placeholders in @p path.
213  */
214  void substitute_value(string &path);
215 
216  /**
217  * @brief Prepare path string for check absolute path.
218  *
219  * Check first char of path string. If it is slash '/', add second slash char. Two slashes
220  * at begin is necessary for correct output of boost::filesystem::path.is_absolute() method
221  * for detection absolute path in unix format ("/home/x/y/z") under cygwin.
222  */
223  static string convert_for_check_absolute(string path);
224 
225 
226  /// Final absolute path to the file.
227  std::shared_ptr<boost::filesystem::path> abs_file_path_;
228 
229  /// File type
231 
232  /// dictionary of placeholders
234 
235  /// Prefix path for output files.
236  static std::shared_ptr<boost::filesystem::path> output_dir;
237 
238  /// Prefix path for input files (directory of the main input file).
239  static std::shared_ptr<boost::filesystem::path> root_dir;
240 };
241 
242 /**
243  * @brief Allow redirect FilePath to stream.
244  */
245 std::ostream& operator<<(std::ostream& stream, const FilePath& fp);
246 
247 
248 #endif /* FILE_NAME_HH_ */
FileType
Possible types of file.
Definition: file_path.hh:67
#define DECLARE_EXCEPTION(ExcName, Format)
Macro for simple definition of exceptions.
Definition: exceptions.hh:158
std::ostream & operator<<(std::ostream &stream, const FilePath &fp)
Allow redirect FilePath to stream.
Definition: file_path.cc:270
static std::shared_ptr< boost::filesystem::path > root_dir
Prefix path for input files (directory of the main input file).
Definition: file_path.hh:239
static constexpr bool value
Definition: json.hpp:87
bool operator==(const Null &, const Null &)
std::shared_ptr< boost::filesystem::path > abs_file_path_
Final absolute path to the file.
Definition: file_path.hh:227
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:194
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
static std::map< string, string > placeholder
dictionary of placeholders
Definition: file_path.hh:233
static std::shared_ptr< boost::filesystem::path > output_dir
Prefix path for output files.
Definition: file_path.hh:236
FileType file_type_
File type.
Definition: file_path.hh:230