26 #pragma comment(lib, "advapi32") 41 static int get_modified_time(
const std::string& path) {
43 HANDLE hFile = CreateFile(path.c_str(), NULL, NULL,
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(
"WARNING: '" + method +
"' is deprecated. " + extra);
184 std::unique_lock<std::mutex> xmlLock(
xml_mutex);
186 int mtime = get_modified_time(path);
191 std::pair<XML_Node*, int> cache =
xmlfiles[path];
192 if (cache.second == mtime) {
199 string::size_type idot = path.rfind(
'.');
202 ext = path.substr(idot, path.size());
207 if (ext !=
".xml" && ext !=
".ctml") {
210 x->
build(phase_xml, path);
221 std::unique_lock<std::mutex> xmlLock(
xml_mutex);
222 std::pair<XML_Node*, int>& entry =
xmlfiles[text];
228 size_t start = text.find_first_not_of(
" \t\r\n");
229 if (text.substr(start,1) ==
"<") {
235 entry.first->build(s,
"[string]");
241 std::unique_lock<std::mutex> xmlLock(
xml_mutex);
244 f.second.first->unlock();
245 delete f.second.first;
256 long int Application::readStringRegistryKey(
const std::string& keyName,
const std::string& valueName,
257 std::string& value,
const std::string& defaultValue)
260 long open_error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_READ, &key);
261 if (open_error != ERROR_SUCCESS) {
264 value = defaultValue;
266 DWORD bufferSize =
sizeof(buffer);
268 error = RegQueryValueEx(key, valueName.c_str(), 0, NULL, (LPBYTE) buffer, &bufferSize);
269 if (ERROR_SUCCESS == error) {
286 if (!errorMessage.empty()) {
287 return errorMessage.back();
289 return "<no Cantera error>";
295 for (
size_t j = 0; j < errorMessage.size(); j++) {
296 f << errorMessage[j] << endl;
298 errorMessage.clear();
303 for (
size_t j = 0; j < errorMessage.size(); j++) {
307 errorMessage.clear();
320 std::string pathsep =
";";
322 std::string pathsep =
":";
325 if (getenv(
"CANTERA_DATA") != 0) {
326 string s = string(getenv(
"CANTERA_DATA"));
328 size_t end = s.find(pathsep);
330 inputDirs.push_back(s.substr(start, end-start));
332 end = s.find(pathsep, start);
334 inputDirs.push_back(s.substr(start,end));
341 std::string installDir;
342 readStringRegistryKey(
"SOFTWARE\\Cantera\\Cantera " CANTERA_SHORT_VERSION,
343 "InstallDir", installDir,
"");
344 if (installDir !=
"") {
345 inputDirs.push_back(installDir +
"data");
349 const char* old_pythonpath = getenv(
"PYTHONPATH");
350 std::string pythonpath =
"PYTHONPATH=" + installDir +
"\\bin";
351 if (old_pythonpath) {
353 pythonpath.append(old_pythonpath);
355 _putenv(pythonpath.c_str());
362 inputDirs.push_back(
"/Applications/Cantera/data");
369 string datadir = string(CANTERA_DATA);
376 std::unique_lock<std::mutex> dirLock(
dir_mutex);
394 std::unique_lock<std::mutex> dirLock(
dir_mutex);
395 string::size_type islash = name.find(
'/');
396 string::size_type ibslash = name.find(
'\\');
400 if (name.find(
"~/") == 0) {
401 char* home = getenv(
"HOME");
403 home = getenv(
"USERPROFILE");
406 return home + name.substr(1,
npos);
411 size_t nd = dirs.size();
412 for (
size_t i = 0; i < nd; i++) {
413 string inname = dirs[i] +
"/" + name;
414 std::ifstream fin(inname);
419 string msg =
"\nInput file " + name +
" not found in director";
420 msg += (nd == 1 ?
"y " :
"ies ");
421 for (
size_t i = 0; i < nd; i++) {
422 msg +=
"\n'" + dirs[i] +
"'";
428 msg +=
"To fix this problem, either:\n";
429 msg +=
" a) move the missing files into the local directory;\n";
430 msg +=
" b) define environment variable CANTERA_DATA to\n";
431 msg +=
" point to the directory containing the file.";
void popError()
Discard the last error message.
static std::mutex app_mutex
Mutex for creating singletons within the application object.
void writelogendl()
Write an end of line character to the screen and flush output.
void writelogendl()
Write an endl to the screen and flush output.
Base class for 'loggers' that write text messages to log files.
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
Class to hold global data.
int getErrorCount()
Return the number of errors that have been encountered so far.
virtual ~Application()
Destructor for class deletes global data.
const size_t npos
index returned by functions to indicate "no position"
static Application * s_app
Pointer to the single Application instance.
Class XML_Node is a tree-based representation of the contents of an XML file.
void writelog(const std::string &msg)
Write a message to the screen.
XML_Node * get_XML_from_string(const std::string &text)
Read a CTI or CTML string and fill up an XML tree.
std::vector< std::string > inputDirs
Current vector of input directories to search for input files.
std::string lastErrorMessage()
Retrieve the last error message in a string.
shared_ptr< Messages > pMessages_t
Typedef for thread specific messages.
std::map< std::string, std::pair< XML_Node *, int > > xmlfiles
Current vector of XML file trees that have been previously parsed The second element of the value is ...
void lock()
Set the lock for this node and all of its children.
static Unit * units()
Initialize the static Unit class.
static std::mutex msg_mutex
Mutex for access to string messages.
Base class for exceptions thrown by Cantera classes.
void setLogger(Logger *logwriter)
Install a logger.
void build(const std::string &filename)
Populate the XML tree from an input file.
std::unique_ptr< Logger > logwriter
Current pointer to the logwriter.
void warn_deprecated(const std::string &method, const std::string &extra="")
Print a warning indicating that method is deprecated.
Header for units conversion utilities, which are used to translate user input from input files (See I...
std::set< std::string > warnings
Vector of deprecation warnings that have been emitted (to suppress duplicates)
XML_Node * get_XML_File(const std::string &file, int debug=0)
Return a pointer to the XML tree for a Cantera input file.
Application()
Constructor for class sets up the initial conditions Protected ctor access thru static member functio...
void thread_complete()
Delete and free memory allocated per thread in multithreaded applications.
static Application * Instance()
Return a pointer to the one and only instance of class Application.
void removeThreadMessages()
Remove a local thread message.
static std::mutex dir_mutex
Mutex for input directory access.
Class to carry out messages.
std::vector< std::string > errorMessage
Current list of error messages.
Contains declarations for string manipulation functions within Cantera.
static std::mutex xml_mutex
Mutex for controlling access to XML file storage.
static void ApplicationDestroy()
Static function that destroys the application class's data.
Namespace for the Cantera kernel.
void writelog(const std::string &msg)
Write a message to the screen.
std::string stripnonprint(const std::string &s)
Strip non-printing characters wherever they are.
Messages * operator->()
Provide a pointer dereferencing overloaded operator.
void addError(const std::string &r, const std::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.
void close_XML_File(const std::string &file)
Close an XML File.