Reference documentation for deal.II version 9.0.0
path_search.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2005 - 2017 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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/path_search.h>
18 #include <deal.II/base/logstream.h>
19 #include <deal.II/base/utilities.h>
20 
21 #include <iostream>
22 #include <cstdio>
23 #include <algorithm>
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) add_class(cls);
77 
78  // Assert(path_lists.count(cls) != 0, ExcNoClass(cls));
79  Assert(path_lists.count(cls) != 0, ExcInternalError());
80 
81  return path_lists.find(cls)->second;
82 }
83 
84 
85 std::vector<std::string> &
86 PathSearch::get_suffix_list(const std::string &cls)
87 {
88  // This is redundant. The constructor should have already called the
89  // add_path function with the path_list bit...
90 
91  // Modified by Luca Heltai. If a class is not there, add it
92  if (suffix_lists.count(cls) == 0) add_class(cls);
93 
94  // Assert(suffix_lists.count(cls) != 0, ExcNoClass(cls));
95  Assert(suffix_lists.count(cls) != 0, ExcInternalError());
96 
97  return suffix_lists.find(cls)->second;
98 }
99 
100 
101 PathSearch::PathSearch(const std::string &cls,
102  const unsigned int debug)
103  :
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 << "] "
123  << my_path_list.size() << " directories "
124  << std::endl;
125 
126  // Try to open file in the various directories we have
127  for (path = my_path_list.begin(); path != endp; ++path)
128  {
129  // see if the file exists as given, i.e., with
130  // the whole filename specified, including (possibly)
131  // the suffix
132  {
133  real_name = *path + filename;
134  if (debug > 1)
135  deallog << "PathSearch[" << cls << "] trying "
136  << real_name << std::endl;
137  FILE *fp = fopen(real_name.c_str(), open_mode);
138  if (fp != nullptr)
139  {
140  if (debug > 0)
141  deallog << "PathSearch[" << cls << "] opened "
142  << real_name << std::endl;
143  fclose(fp);
144  return real_name;
145  }
146  }
147 
148  // try again with the suffix appended, unless there is
149  // no suffix
150  if (suffix != "")
151  {
152  real_name = *path + filename + suffix;
153  if (debug > 1)
154  deallog << "PathSearch[" << cls << "] trying "
155  << real_name << std::endl;
156  FILE *fp = fopen(real_name.c_str(), open_mode);
157  if (fp != nullptr)
158  {
159  if (debug > 0)
160  deallog << "PathSearch[" << cls << "] opened "
161  << real_name << std::endl;
162  fclose(fp);
163  return real_name;
164  }
165  }
166  }
167  AssertThrow(false, ExcFileNotFound(filename, cls));
168  return std::string("");
169 }
170 
171 std::string
172 PathSearch::find (const std::string &filename,
173  const char *open_mode)
174 {
175  std::vector<std::string>::const_iterator suffix;
176  const std::vector<std::string>::const_iterator ends = my_suffix_list.end();
177 
178  if (debug > 2)
179  deallog << "PathSearch[" << cls << "] "
180  << my_path_list.size() << " directories "
181  << my_suffix_list.size() << " suffixes"
182  << std::endl;
183 
184  for (suffix = my_suffix_list.begin(); suffix != ends; ++suffix)
185  {
186  try
187  {
188  return find(filename, *suffix, open_mode);
189  }
190  catch (ExcFileNotFound &)
191  {
192  continue;
193  }
194 
195  }
196  AssertThrow(false, ExcFileNotFound(filename, cls));
197  return std::string("");
198 }
199 
200 
201 void
202 PathSearch::add_class (const std::string &cls)
203 {
204  // Make sure standard classes are
205  // initialized first
206  if (path_lists.empty())
208  // Add empty path and empty suffix
209  // for new class
210  std::vector<std::string> v;
211  v.emplace_back();
212  path_lists.insert(map_type(cls, v));
213  suffix_lists.insert(map_type(cls, v));
214 }
215 
216 
217 void
218 PathSearch::add_path (const std::string &path,
219  Position pos)
220 {
221  if (pos == back)
222  my_path_list.push_back(path);
223  else if (pos == front)
224  my_path_list.insert(my_path_list.begin(), path);
225  else if (pos == after_none)
226  {
227  std::vector<std::string>::iterator
228  i = std::find(my_path_list.begin(), my_path_list.end(), empty);
229  if (i != my_path_list.end())
230  ++i;
231  my_path_list.insert(i, path);
232  }
233 }
234 
235 
236 void
237 PathSearch::add_suffix (const std::string &suffix,
238  Position pos)
239 {
240  if (pos == back)
241  my_suffix_list.push_back(suffix);
242  else if (pos == front)
243  my_suffix_list.insert(my_suffix_list.begin(), suffix);
244  else if (pos == after_none)
245  {
246  std::vector<std::string>::iterator
247  i = std::find(my_suffix_list.begin(), my_suffix_list.end(), empty);
248  if (i != my_suffix_list.end())
249  ++i;
250  my_suffix_list.insert(i, suffix);
251  }
252 }
253 
254 
255 
256 DEAL_II_NAMESPACE_CLOSE
static std::string empty
Definition: path_search.h:247
Add in path list after empty element.
Definition: path_search.h:96
static std::map< std::string, std::vector< std::string > > path_lists
Definition: path_search.h:222
static void add_class(const std::string &cls)
Definition: path_search.cc:202
void add_path(const std::string &path, Position pos=back)
Definition: path_search.cc:218
const unsigned int debug
Definition: path_search.h:242
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
static std::map< std::string, std::vector< std::string > > suffix_lists
Definition: path_search.h:227
static std::vector< std::string > & get_suffix_list(const std::string &cls)
Definition: path_search.cc:86
Add new item at end of list.
Definition: path_search.h:92
std::vector< std::string > & my_suffix_list
Definition: path_search.h:237
static ::ExceptionBase & ExcFileNotFound(std::string arg1, std::string arg2)
const std::string cls
Definition: path_search.h:217
static void initialize_classes()
Definition: path_search.cc:33
std::vector< std::string > & my_path_list
Definition: path_search.h:232
#define Assert(cond, exc)
Definition: exceptions.h:1142
std::string find(const std::string &filename, const char *open_mode="r")
Definition: path_search.cc:172
std::map< std::string, std::vector< std::string > >::value_type map_type
Definition: path_search.h:195
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:237
PathSearch(const std::string &cls, const unsigned int debug=0)
Definition: path_search.cc:101
Add new item at front of list.
Definition: path_search.h:94
static ::ExceptionBase & ExcInternalError()