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