Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
path_search.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2005 - 2019 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/logstream.h>
18 #include <deal.II/base/path_search.h>
19 #include <deal.II/base/utilities.h>
20 
21 #include <algorithm>
22 #include <cstdio>
23 #include <iostream>
24 
25 DEAL_II_NAMESPACE_OPEN
26 
27 
28 std::map<std::string, std::vector<std::string>> PathSearch::path_lists;
29 std::map<std::string, std::vector<std::string>> PathSearch::suffix_lists;
30 std::string PathSearch::empty("");
31 
32 void
34 {
35  std::vector<std::string> v;
36  v.emplace_back();
37  path_lists.insert(map_type(std::string("PARAMETER"), v));
38 
39  /*
40  * TODO: reenable some sensible default paths. Maier, 2012
41  */
42  path_lists.insert(map_type(std::string("MESH"), v));
43 
44  v.clear();
45  v.emplace_back();
46  v.emplace_back(".prm");
47  suffix_lists.insert(map_type(std::string("PARAMETER"), v));
48 
49  /*
50  * TODO: "Would require linking with the deal.II libraries"? This .cc
51  * file gets compiled into the library... maier, 2012
52  */
53  // We cannot use the GridIn class
54  // to query the formats, since this
55  // would require linking with the
56  // deal.II libraries.
57  v.clear();
58  v.emplace_back();
59  v.emplace_back(".inp");
60  v.emplace_back(".xda");
61  v.emplace_back(".dbmesh");
62  v.emplace_back(".dat");
63  v.emplace_back(".plt");
64  v.emplace_back(".nc");
65  v.emplace_back(".msh");
66  suffix_lists.insert(map_type(std::string("MESH"), v));
67 }
68 
69 std::vector<std::string> &
70 PathSearch::get_path_list(const std::string &cls)
71 {
72  if (path_lists.empty())
74 
75  // Modified by Luca Heltai. If a class is not there, add it
76  if (path_lists.count(cls) == 0)
77  add_class(cls);
78 
79  // Assert(path_lists.count(cls) != 0, ExcNoClass(cls));
80  Assert(path_lists.count(cls) != 0, ExcInternalError());
81 
82  return path_lists.find(cls)->second;
83 }
84 
85 
86 std::vector<std::string> &
87 PathSearch::get_suffix_list(const std::string &cls)
88 {
89  // This is redundant. The constructor should have already called the
90  // add_path function with the path_list bit...
91 
92  // Modified by Luca Heltai. If a class is not there, add it
93  if (suffix_lists.count(cls) == 0)
94  add_class(cls);
95 
96  // Assert(suffix_lists.count(cls) != 0, ExcNoClass(cls));
97  Assert(suffix_lists.count(cls) != 0, ExcInternalError());
98 
99  return suffix_lists.find(cls)->second;
100 }
101 
102 
103 PathSearch::PathSearch(const std::string &cls, const unsigned int debug)
104  : cls(cls)
105  , my_path_list(get_path_list(cls))
106  , my_suffix_list(get_suffix_list(cls))
107  , debug(debug)
108 {}
109 
110 
111 std::string
112 PathSearch::find(const std::string &filename,
113  const std::string &suffix,
114  const char * open_mode)
115 {
116  std::vector<std::string>::const_iterator path;
117  const std::vector<std::string>::const_iterator endp = my_path_list.end();
118 
119  std::string real_name;
120 
121  if (debug > 2)
122  deallog << "PathSearch[" << cls << "] " << my_path_list.size()
123  << " directories " << std::endl;
124 
125  // Try to open file in the various directories we have
126  for (path = my_path_list.begin(); path != endp; ++path)
127  {
128  // see if the file exists as given, i.e., with
129  // the whole filename specified, including (possibly)
130  // the suffix
131  {
132  real_name = *path + filename;
133  if (debug > 1)
134  deallog << "PathSearch[" << cls << "] trying " << real_name
135  << std::endl;
136  FILE *fp = fopen(real_name.c_str(), open_mode);
137  if (fp != nullptr)
138  {
139  if (debug > 0)
140  deallog << "PathSearch[" << cls << "] opened " << real_name
141  << std::endl;
142  fclose(fp);
143  return real_name;
144  }
145  }
146 
147  // try again with the suffix appended, unless there is
148  // no suffix
149  if (!suffix.empty())
150  {
151  real_name = *path + filename + suffix;
152  if (debug > 1)
153  deallog << "PathSearch[" << cls << "] trying " << real_name
154  << std::endl;
155  FILE *fp = fopen(real_name.c_str(), open_mode);
156  if (fp != nullptr)
157  {
158  if (debug > 0)
159  deallog << "PathSearch[" << cls << "] opened " << real_name
160  << std::endl;
161  fclose(fp);
162  return real_name;
163  }
164  }
165  }
166  AssertThrow(false, ExcFileNotFound(filename, cls));
167  return std::string("");
168 }
169 
170 std::string
171 PathSearch::find(const std::string &filename, const char *open_mode)
172 {
173  std::vector<std::string>::const_iterator suffix;
174  const std::vector<std::string>::const_iterator ends = my_suffix_list.end();
175 
176  if (debug > 2)
177  deallog << "PathSearch[" << cls << "] " << my_path_list.size()
178  << " directories " << my_suffix_list.size() << " suffixes"
179  << std::endl;
180 
181  for (suffix = my_suffix_list.begin(); suffix != ends; ++suffix)
182  {
183  try
184  {
185  return find(filename, *suffix, open_mode);
186  }
187  catch (ExcFileNotFound &)
188  {
189  continue;
190  }
191  }
192  AssertThrow(false, ExcFileNotFound(filename, cls));
193  return std::string("");
194 }
195 
196 
197 void
198 PathSearch::add_class(const std::string &cls)
199 {
200  // Make sure standard classes are
201  // initialized first
202  if (path_lists.empty())
204  // Add empty path and empty suffix
205  // for new class
206  std::vector<std::string> v;
207  v.emplace_back();
208  path_lists.insert(map_type(cls, v));
209  suffix_lists.insert(map_type(cls, v));
210 }
211 
212 
213 void
214 PathSearch::add_path(const std::string &path, Position pos)
215 {
216  if (pos == back)
217  my_path_list.push_back(path);
218  else if (pos == front)
219  my_path_list.insert(my_path_list.begin(), path);
220  else if (pos == after_none)
221  {
222  std::vector<std::string>::iterator i =
223  std::find(my_path_list.begin(), my_path_list.end(), empty);
224  if (i != my_path_list.end())
225  ++i;
226  my_path_list.insert(i, path);
227  }
228 }
229 
230 
231 void
232 PathSearch::add_suffix(const std::string &suffix, Position pos)
233 {
234  if (pos == back)
235  my_suffix_list.push_back(suffix);
236  else if (pos == front)
237  my_suffix_list.insert(my_suffix_list.begin(), suffix);
238  else if (pos == after_none)
239  {
240  std::vector<std::string>::iterator i =
241  std::find(my_suffix_list.begin(), my_suffix_list.end(), empty);
242  if (i != my_suffix_list.end())
243  ++i;
244  my_suffix_list.insert(i, suffix);
245  }
246 }
247 
248 
249 
250 DEAL_II_NAMESPACE_CLOSE
static std::string empty
Definition: path_search.h:255
Add in path list after empty element.
Definition: path_search.h:97
static std::map< std::string, std::vector< std::string > > path_lists
Definition: path_search.h:230
static void add_class(const std::string &cls)
Definition: path_search.cc:198
void add_path(const std::string &path, Position pos=back)
Definition: path_search.cc:214
const unsigned int debug
Definition: path_search.h:250
#define AssertThrow(cond, exc)
Definition: exceptions.h:1519
static std::map< std::string, std::vector< std::string > > suffix_lists
Definition: path_search.h:235
static std::vector< std::string > & get_suffix_list(const std::string &cls)
Definition: path_search.cc:87
Add new item at end of list.
Definition: path_search.h:93
std::vector< std::string > & my_suffix_list
Definition: path_search.h:245
std::map< std::string, std::vector< std::string > >::value_type map_type
Definition: path_search.h:200
static ::ExceptionBase & ExcFileNotFound(std::string arg1, std::string arg2)
const std::string cls
Definition: path_search.h:225
static void initialize_classes()
Definition: path_search.cc:33
std::vector< std::string > & my_path_list
Definition: path_search.h:240
#define Assert(cond, exc)
Definition: exceptions.h:1407
std::string find(const std::string &filename, const char *open_mode="r")
Definition: path_search.cc:171
static std::vector< std::string > & get_path_list(const std::string &cls)
Definition: path_search.cc:70
void add_suffix(const std::string &suffix, Position pos=back)
Definition: path_search.cc:232
PathSearch(const std::string &cls, const unsigned int debug=0)
Definition: path_search.cc:103
Add new item at front of list.
Definition: path_search.h:95
static ::ExceptionBase & ExcInternalError()