26 #pragma comment(lib, "advapi32")
41 int get_modified_time(
const std::string& path) {
43 HANDLE hFile = CreateFile(path.c_str(), 0, 0,
44 NULL, OPEN_EXISTING, 0, NULL);
45 if (hFile == INVALID_HANDLE_VALUE) {
46 throw CanteraError(
"get_modified_time",
"Couldn't open file:" + path);
49 GetFileTime(hFile, NULL, NULL, &modified);
51 return static_cast<int>(modified.dwLowDateTime);
54 stat(path.c_str(), &attrib);
55 return static_cast<int>(attrib.st_mtime);
59 Application::Messages::Messages()
68 if (msg.size() != 0) {
69 errorMessage.push_back(
70 "\n\n************************************************\n"
72 "************************************************\n\n"
74 "\nError: " + msg +
"\n");
76 errorMessage.push_back(r);
82 return static_cast<int>(errorMessage.size());
87 logwriter.reset(_logwriter);
92 logwriter->write(msg);
97 logwriter->writeendl();
105 std::unique_lock<std::mutex> msgLock(
msg_mutex);
106 std::thread::id curId = std::this_thread::get_id();
107 auto iter = m_threadMsgMap.find(curId);
108 if (iter != m_threadMsgMap.end()) {
109 return iter->second.get();
112 m_threadMsgMap.insert({curId, pMsgs});
118 std::unique_lock<std::mutex> msgLock(
msg_mutex);
119 std::thread::id curId = std::this_thread::get_id();
120 auto iter = m_threadMsgMap.find(curId);
121 if (iter != m_threadMsgMap.end()) {
122 m_threadMsgMap.erase(iter);
127 m_suppress_deprecation_warnings(false),
128 m_fatal_deprecation_warnings(false),
129 m_suppress_thermo_warnings(false)
139 std::unique_lock<std::mutex> appLock(
app_mutex);
149 f.second.first->unlock();
150 delete f.second.first;
157 std::unique_lock<std::mutex> appLock(
app_mutex);
165 const std::string& extra)
167 if (m_fatal_deprecation_warnings) {
169 }
else if (m_suppress_deprecation_warnings ||
warnings.count(method)) {
173 writelog(fmt::format(
"DeprecationWarning: {}: {}", method, extra));
178 const std::string& extra)
180 writelog(fmt::format(
"CanteraWarning: {}: {}", method, extra));
191 std::unique_lock<std::mutex> xmlLock(
xml_mutex);
193 int mtime = get_modified_time(path);
198 std::pair<XML_Node*, int> cache =
xmlfiles[path];
199 if (cache.second == mtime) {
206 string::size_type idot = path.rfind(
'.');
209 ext = path.substr(idot, path.size());
214 if (ext !=
".xml" && ext !=
".ctml") {
217 x->
build(phase_xml, path);
228 std::unique_lock<std::mutex> xmlLock(
xml_mutex);
229 std::pair<XML_Node*, int>& entry =
xmlfiles[text];
235 size_t start = text.find_first_not_of(
" \t\r\n");
236 if (text.substr(start,1) ==
"<") {
242 entry.first->build(s,
"[string]");
248 std::unique_lock<std::mutex> xmlLock(
xml_mutex);
251 f.second.first->unlock();
252 delete f.second.first;
263 long int Application::readStringRegistryKey(
const std::string& keyName,
const std::string& valueName,
264 std::string& value,
const std::string& defaultValue)
267 long open_error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_READ, &key);
268 if (open_error != ERROR_SUCCESS) {
271 value = defaultValue;
273 DWORD bufferSize =
sizeof(buffer);
275 error = RegQueryValueEx(key, valueName.c_str(), 0, NULL, (LPBYTE) buffer, &bufferSize);
276 if (ERROR_SUCCESS == error) {
293 if (!errorMessage.empty()) {
294 return errorMessage.back();
296 return "<no Cantera error>";
302 for (
size_t j = 0; j < errorMessage.size(); j++) {
303 f << errorMessage[j] << endl;
305 errorMessage.clear();
310 for (
size_t j = 0; j < errorMessage.size(); j++) {
314 errorMessage.clear();
327 std::string pathsep =
";";
329 std::string pathsep =
":";
332 if (getenv(
"CANTERA_DATA") != 0) {
333 string s = string(getenv(
"CANTERA_DATA"));
335 size_t end = s.find(pathsep);
337 inputDirs.push_back(s.substr(start, end-start));
339 end = s.find(pathsep, start);
341 inputDirs.push_back(s.substr(start,end));
348 std::string installDir;
349 readStringRegistryKey(
"SOFTWARE\\Cantera\\Cantera " CANTERA_SHORT_VERSION,
350 "InstallDir", installDir,
"");
351 if (installDir !=
"") {
352 inputDirs.push_back(installDir +
"data");
356 const char* old_pythonpath = getenv(
"PYTHONPATH");
357 std::string pythonpath =
"PYTHONPATH=" + installDir +
"\\bin";
358 if (old_pythonpath) {
360 pythonpath.append(old_pythonpath);
362 _putenv(pythonpath.c_str());
369 inputDirs.push_back(
"/Applications/Cantera/data");
376 string datadir = string(CANTERA_DATA);
383 std::unique_lock<std::mutex> dirLock(
dir_mutex);
390 if (d.find(
"~/") == 0 || d.find(
"~\\") == 0) {
391 char* home = getenv(
"HOME");
393 home = getenv(
"USERPROFILE");
396 d = home + d.substr(1,
npos);
412 std::unique_lock<std::mutex> dirLock(
dir_mutex);
413 string::size_type islash = name.find(
'/');
414 string::size_type ibslash = name.find(
'\\');
415 string::size_type icolon = name.find(
':');
419 if (name.find(
"~/") == 0 || name.find(
"~\\") == 0) {
420 char* home = getenv(
"HOME");
422 home = getenv(
"USERPROFILE");
425 string full_name = home + name.substr(1,
npos);
426 std::ifstream fin(full_name);
431 "Input file '{}' not found", name);
437 if (islash == 0 || ibslash == 0
438 || (icolon == 1 && (ibslash == 2 || islash == 2)))
440 std::ifstream fin(name);
445 "Input file '{}' not found", name);
451 size_t nd = dirs.size();
452 for (
size_t i = 0; i < nd; i++) {
453 string full_name = dirs[i] +
"/" + name;
454 std::ifstream fin(full_name);
459 string msg =
"\nInput file " + name +
" not found in director";
460 msg += (nd == 1 ?
"y " :
"ies ");
461 for (
size_t i = 0; i < nd; i++) {
462 msg +=
"\n'" + dirs[i] +
"'";
468 msg +=
"To fix this problem, either:\n";
469 msg +=
" a) move the missing files into the local directory;\n";
470 msg +=
" b) define environment variable CANTERA_DATA to\n";
471 msg +=
" point to the directory containing the file.";