Loading [MathJax]/extensions/TeX/newcommand.js
 deal.II version GIT relicensing-3087-ga35b476a78 2025-04-19 20:30:01+00:00
\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}} \newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=} \newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]} \newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
path_search.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2005 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15
20
21#include <algorithm>
22#include <cstdio>
23#include <iostream>
24
26
27
28std::map<std::string, std::vector<std::string>> PathSearch::path_lists;
29std::map<std::string, std::vector<std::string>> PathSearch::suffix_lists;
30std::string PathSearch::empty("");
31
32void
34{
35 std::vector<std::string> v;
36 v.emplace_back();
37 path_lists.insert(map_type("PARAMETER", v));
38
39 /*
40 * TODO: re-enable some sensible default paths. Maier, 2012
41 */
42 path_lists.insert(map_type("MESH", v));
43
44 v.clear();
45 v.emplace_back();
46 v.emplace_back(".prm");
47 suffix_lists.insert(map_type("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("MESH", v));
67}
68
69std::vector<std::string> &
70PathSearch::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)
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
86std::vector<std::string> &
87PathSearch::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)
95
96 // Assert(suffix_lists.count(cls) != 0, ExcNoClass(cls));
98
99 return suffix_lists.find(cls)->second;
100}
101
102
103PathSearch::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
111std::string
112PathSearch::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 std::FILE *fp = std::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 std::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 std::FILE *fp = std::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 std::fclose(fp);
162 return real_name;
163 }
164 }
165 }
166 AssertThrow(false, ExcFileNotFound(filename, cls));
167 return "";
168}
169
170std::string
171PathSearch::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 "";
194}
195
196
197void
198PathSearch::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
213void
214PathSearch::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
231void
232PathSearch::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
std::string find(const std::string &filename, const char *open_mode="r")
static std::vector< std::string > & get_path_list(const std::string &cls)
static std::vector< std::string > & get_suffix_list(const std::string &cls)
static std::map< std::string, std::vector< std::string > > path_lists
const std::string cls
void add_path(const std::string &path, Position pos=back)
std::vector< std::string > & my_suffix_list
static std::map< std::string, std::vector< std::string > > suffix_lists
static void add_class(const std::string &cls)
const unsigned int debug
std::vector< std::string > & my_path_list
@ back
Add new item at end of list.
Definition path_search.h:91
@ after_none
Add in path list after empty element.
Definition path_search.h:95
@ front
Add new item at front of list.
Definition path_search.h:93
void add_suffix(const std::string &suffix, Position pos=back)
std::map< std::string, std::vector< std::string > >::value_type map_type
PathSearch(const std::string &cls, const unsigned int debug=0)
static std::string empty
static void initialize_classes()
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:35
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:36
static ::ExceptionBase & ExcFileNotFound(std::string arg1, std::string arg2)
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
#define AssertThrow(cond, exc)
LogStream deallog
Definition logstream.cc:38