11#define BOOST_DLL_USE_STD_FS
12#include <boost/dll/import.hpp>
13#include <boost/algorithm/string.hpp>
19namespace ba = boost::algorithm;
26#pragma comment(lib, "advapi32")
40 if (msg.size() != 0) {
42 "\n\n************************************************\n"
44 "************************************************\n\n"
46 "\nError: " + msg +
"\n");
54 return static_cast<int>(errorMessage.size());
62 std::unique_lock<std::mutex> msgLock(
msg_mutex);
63 std::thread::id curId = std::this_thread::get_id();
64 auto iter = m_threadMsgMap.find(curId);
65 if (iter != m_threadMsgMap.end()) {
66 return iter->second.get();
69 m_threadMsgMap.insert({curId, pMsgs});
75 std::unique_lock<std::mutex> msgLock(
msg_mutex);
76 std::thread::id curId = std::this_thread::get_id();
77 auto iter = m_threadMsgMap.find(curId);
78 if (iter != m_threadMsgMap.end()) {
79 m_threadMsgMap.erase(iter);
92 if (getenv(
"CANTERA_FATAL_DEPRECATION_WARNINGS") !=
nullptr) {
99 std::unique_lock<std::mutex> appLock(
app_mutex);
108 std::unique_lock<std::mutex> appLock(
app_mutex);
117 if (m_fatal_deprecation_warnings) {
119 }
else if (m_suppress_deprecation_warnings ||
warnings.count(method)) {
123 warnlog(
"Deprecation", fmt::format(
"{}: {}", method, extra));
128 if (m_fatal_warnings) {
130 }
else if (m_suppress_warnings) {
133 warnlog(warning, fmt::format(
"{}: {}", method, extra));
142long int Application::readStringRegistryKey(
const string& keyName,
const string& valueName,
143 string& value,
const string& defaultValue)
146 long open_error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_READ, &key);
147 if (open_error != ERROR_SUCCESS) {
150 value = defaultValue;
152 DWORD bufferSize =
sizeof(buffer);
154 error = RegQueryValueEx(key, valueName.c_str(), 0, NULL, (LPBYTE) buffer, &bufferSize);
155 if (ERROR_SUCCESS == error) {
165 if (!errorMessage.empty()) {
166 errorMessage.pop_back();
172 if (!errorMessage.empty()) {
173 return errorMessage.back();
175 return "<no Cantera error>";
181 for (
size_t j = 0; j < errorMessage.size(); j++) {
182 f << errorMessage[j] << std::endl;
184 errorMessage.clear();
189 for (
size_t j = 0; j < errorMessage.size(); j++) {
193 errorMessage.clear();
228 string pathsep =
";";
229 string dirsep =
"\\";
231 string pathsep =
":";
235 if (getenv(
"CANTERA_DATA") !=
nullptr) {
236 string s(getenv(
"CANTERA_DATA"));
238 size_t end = s.find(pathsep);
239 while (end !=
npos) {
240 inputDirs.push_back(s.substr(start, end-start));
242 end = s.find(pathsep, start);
244 inputDirs.push_back(s.substr(start,end));
249 if (getenv(
"CONDA_PREFIX") !=
nullptr) {
250 string s(getenv(
"CONDA_PREFIX"));
251 inputDirs.push_back(s + dirsep +
"share" + dirsep +
"cantera" + dirsep +
"data");
259 readStringRegistryKey(
"SOFTWARE\\Cantera\\Cantera " CANTERA_SHORT_VERSION,
260 "InstallDir", installDir,
"");
261 if (installDir !=
"") {
262 inputDirs.push_back(installDir +
"data");
266 const char* old_pythonpath = getenv(
"PYTHONPATH");
267 string pythonpath =
"PYTHONPATH=" + installDir +
"\\bin";
268 if (old_pythonpath) {
270 pythonpath.append(old_pythonpath);
272 _putenv(pythonpath.c_str());
288 std::unique_lock<std::mutex> dirLock(
dir_mutex);
295 if (d.find(
"~/") == 0 || d.find(
"~\\") == 0) {
296 char* home = getenv(
"HOME");
298 home = getenv(
"USERPROFILE");
301 d = home + d.substr(1,
npos);
317 std::unique_lock<std::mutex> dirLock(
dir_mutex);
318 string::size_type islash = name.find(
'/');
319 string::size_type ibslash = name.find(
'\\');
320 string::size_type icolon = name.find(
':');
324 if (name.find(
"~/") == 0 || name.find(
"~\\") == 0) {
325 char* home = getenv(
"HOME");
327 home = getenv(
"USERPROFILE");
330 string full_name = home + name.substr(1,
npos);
331 std::ifstream fin(full_name);
336 "Input file '{}' not found", name);
342 if (islash == 0 || ibslash == 0
343 || (icolon == 1 && (ibslash == 2 || islash == 2)))
345 std::ifstream fin(name);
350 "Input file '{}' not found", name);
356 size_t nd = dirs.size();
357 for (
size_t i = 0; i < nd; i++) {
358 string full_name = dirs[i] +
"/" + name;
359 std::ifstream fin(full_name);
364 string msg =
"\nInput file " + name +
" not found in director";
365 msg += (nd == 1 ?
"y " :
"ies ");
366 for (
size_t i = 0; i < nd; i++) {
367 msg +=
"\n'" + dirs[i] +
"'";
373 msg +=
"To fix this problem, either:\n";
374 msg +=
" a) move the missing files into the local directory;\n";
375 msg +=
" b) define environment variable CANTERA_DATA to\n";
376 msg +=
" point to the directory containing the file.";
384 "Loading extensions requires linking to the Cantera shared library\n"
385 "rather than the static library");
387 if (m_loaded_extensions.count({extType, name})) {
395 typedef void (loader_t)();
399 static function<loader_t> loader;
403 string py_ver_underscore = ba::replace_all_copy(py_ver,
".",
"_");
405 loader = boost::dll::import_alias<loader_t>(
406 "cantera_python" + py_ver_underscore,
407 "registerPythonExtensionManager",
410 boost::dll::load_mode::search_system_folders
411 | boost::dll::load_mode::append_decorations
412 | boost::dll::load_mode::rtld_global
417 }
catch (std::exception& err) {
418 errors += fmt::format(
"\nPython {}: {}\n", py_ver, err.what());
423 "Error loading Python extension support. Tried the following:{}",
428 m_loaded_extensions.insert({extType, name});
Class to carry out messages.
vector< string > errorMessage
Current list of error messages.
Messages * operator->()
Provide a pointer dereferencing overloaded operator.
void removeThreadMessages()
Remove a local thread message.
Class to hold global data.
static Application * s_app
Pointer to the single Application instance.
vector< string > m_pythonSearchVersions
Versions of Python to consider when attempting to load user extensions.
unique_ptr< Logger > m_logwriter
Current log writer.
void make_deprecation_warnings_fatal()
Turns deprecation warnings into exceptions.
static Application * Instance()
Return a pointer to the one and only instance of class Application.
void loadExtension(const string &extType, const string &name)
Load an extension implementing user-defined models.
void warn_deprecated(const string &method, const string &extra="")
Print a warning indicating that method is deprecated.
void searchPythonVersions(const string &versions)
Set the versions of Python to try when loading user-defined extensions, in order of preference.
vector< string > inputDirs
Current vector of input directories to search for input files.
void thread_complete()
Delete and free memory allocated per thread in multithreaded applications.
set< string > warnings
Set of deprecation warnings that have been emitted (to suppress duplicates)
shared_ptr< Messages > pMessages_t
Typedef for thread specific messages.
Application()
Constructor for class sets up the initial conditions Protected ctor access thru static member functio...
void writelogendl()
Write an end of line character to the logger and flush output.
static void ApplicationDestroy()
Static function that destroys the application class's data.
void warn(const string &warning, const string &method, const string &extra="")
Generate a general purpose warning; repeated warnings are not suppressed.
Base class for exceptions thrown by Cantera classes.
static shared_ptr< ExtensionManager > build(const string &extensionType)
Create a new ExtensionManager.
static ExtensionManagerFactory & factory()
Static function that returns the static instance of the factory, creating it if necessary.
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
string stripnonprint(const string &s)
Strip non-printing characters wherever they are.
void addError(const string &r, const string &msg="")
Set an error condition in the application class without throwing an exception.
void logErrors()
Prints all of the error messages using writelog.
void getErrors(std::ostream &f)
Prints all of the error messages to an ostream.
string lastErrorMessage()
Retrieve the last error message in a string.
int getErrorCount()
Return the number of errors that have been encountered so far.
void popError()
Discard the last error message.
bool usingSharedLibrary()
Returns true if Cantera was loaded as a shared library in the current application.
void warnlog(const string &warning, const string &msg)
Write a warning message to the logger.
void setLogger(unique_ptr< Logger > logwriter)
Install a Logger.
void writelog(const string &msg)
Write a message to the logger.
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
void writelogendl()
Write an end of line character to the screen and flush output.
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
static std::mutex app_mutex
Mutex for creating singletons within the application object.
static std::mutex dir_mutex
Mutex for input directory access.
static std::mutex msg_mutex
Mutex for access to string messages.
Contains declarations for string manipulation functions within Cantera.