21 #pragma comment(lib, "advapi32")
30 #ifdef THREAD_SAFE_CANTERA
31 cthreadId_t getThisThreadId()
33 #if defined(BOOST_HAS_WINTHREADS)
34 return ::GetCurrentThreadId();
35 #elif defined(BOOST_HAS_PTHREADS)
36 return pthread_self();
51 static int get_modified_time(
const std::string& path) {
53 HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_WRITE,
54 NULL, OPEN_EXISTING, 0, NULL);
55 if (hFile == INVALID_HANDLE_VALUE) {
56 throw CanteraError(
"get_modified_time",
"Couldn't open file:" + path);
59 GetFileTime(hFile, NULL, NULL, &modified);
61 return static_cast<int>(modified.dwLowDateTime);
64 stat(path.c_str(), &attrib);
65 return static_cast<int>(attrib.st_mtime);
78 errorMessage(r.errorMessage),
79 errorRoutine(r.errorRoutine),
93 errorRoutine = r.errorRoutine;
94 logwriter =
new Logger(*(r.logwriter));
98 Application::Messages::~Messages()
105 errorMessage.push_back(msg);
106 errorRoutine.push_back(r);
111 return static_cast<int>(errorMessage.size()) ;
116 if (logwriter == _logwriter) {
119 if (logwriter != 0) {
123 logwriter = _logwriter;
129 logwriter->error(msg) ;
134 logwriter->write(msg);
139 logwriter->writeendl();
142 #ifdef THREAD_SAFE_CANTERA
150 cthreadId_t curId = getThisThreadId() ;
151 threadMsgMap_t::iterator iter = m_threadMsgMap.find(curId) ;
152 if (iter != m_threadMsgMap.end()) {
153 return iter->second.get();
156 m_threadMsgMap.insert(std::pair< cthreadId_t, pMessages_t >(curId, pMsgs)) ;
163 cthreadId_t curId = getThisThreadId() ;
164 threadMsgMap_t::iterator iter = m_threadMsgMap.find(curId) ;
165 if (iter != m_threadMsgMap.end()) {
166 m_threadMsgMap.erase(iter) ;
169 #endif // THREAD_SAFE_CANTERA
173 m_suppress_deprecation_warnings(false)
175 #if !defined( THREAD_SAFE_CANTERA )
182 #if defined(THREAD_SAFE_CANTERA)
198 std::map<std::string, std::pair<XML_Node*, int> >::iterator pos;
200 pos->second.first->unlock();
201 delete pos->second.first;
202 pos->second.first = 0;
216 const std::string& extra)
218 if (m_suppress_deprecation_warnings ||
warnings.count(method)) {
222 writelog(
"WARNING: '" + method +
"' is deprecated. " + extra);
228 #if defined(THREAD_SAFE_CANTERA)
236 std::string path =
"";
238 int mtime = get_modified_time(path);
243 std::pair<XML_Node*, int> cache =
xmlfiles[path];
244 if (cache.second == mtime) {
252 string::size_type idot = path.rfind(
'.');
255 ext = path.substr(idot, path.size());
260 if (ext !=
".xml" && ext !=
".ctml") {
265 std::ifstream s(path.c_str());
270 "cannot open "+file+
" for reading.\n"
271 "Note, this error indicates a possible configuration problem.");
275 xmlfiles[path] = std::make_pair(x, mtime);
282 std::pair<XML_Node*, int>& entry =
xmlfiles[text];
288 size_t start = text.find_first_not_of(
" \t\r\n");
289 if (text.substr(start,1) ==
"<") {
295 entry.first->build(s);
303 std::map<string, std::pair<XML_Node*, int> >::iterator
306 for (; b != e; ++b) {
307 b->second.first->unlock();
308 delete b->second.first;
319 long int Application::readStringRegistryKey(
const std::string& keyName,
const std::string& valueName,
320 std::string& value,
const std::string& defaultValue)
324 long open_error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_READ, &key);
325 if (open_error != ERROR_SUCCESS) {
328 value = defaultValue;
330 DWORD bufferSize =
sizeof(buffer);
332 error = RegQueryValueEx(key, valueName.c_str(), 0, NULL, (LPBYTE) buffer, &bufferSize);
333 if (ERROR_SUCCESS == error) {
351 if (!errorMessage.empty()) {
353 "\n\n************************************************\n"
355 "************************************************\n\n";
356 return head+string(
"\nProcedure: ")+errorRoutine.back()
357 +string(
"\nError: ")+errorMessage.back();
359 return "<no Cantera error>";
365 size_t i = errorMessage.size();
370 f <<
"************************************************" << endl;
371 f <<
" Cantera Error! " << endl;
372 f <<
"************************************************" << endl
374 for (
size_t j = 0; j < i; j++) {
376 f <<
"Procedure: " << errorRoutine[j] << endl;
377 f <<
"Error: " << errorMessage[j] << endl;
380 errorMessage.clear();
381 errorRoutine.clear();
386 size_t i = errorMessage.size();
391 writelog(
"************************************************\n");
393 writelog(
"************************************************\n\n");
394 for (
size_t j = 0; j < i; j++) {
396 writelog(
string(
"Procedure: ")+ errorRoutine[j]+
" \n");
397 writelog(
string(
"Error: ")+ errorMessage[j]+
" \n");
400 errorMessage.clear();
401 errorRoutine.clear();
416 std::string installDir;
417 readStringRegistryKey(
"SOFTWARE\\Cantera\\Cantera 2.2",
418 "InstallDir", installDir,
"");
419 if (installDir !=
"") {
420 dirs.push_back(installDir +
"data");
424 const char* old_pythonpath = getenv(
"PYTHONPATH");
425 std::string pythonpath =
"PYTHONPATH=" + installDir +
"\\bin";
426 if (old_pythonpath) {
428 pythonpath.append(old_pythonpath);
430 putenv(pythonpath.c_str());
439 dirs.push_back(
"/Applications/Cantera/data");
447 std::string pathsep =
";";
449 std::string pathsep =
":";
452 if (getenv(
"CANTERA_DATA") != 0) {
453 string s = string(getenv(
"CANTERA_DATA"));
455 size_t end = s.find(pathsep);
457 dirs.push_back(s.substr(start, end-start));
459 end = s.find(pathsep, start);
461 dirs.push_back(s.substr(start,end));
469 string datadir = string(CANTERA_DATA);
470 dirs.push_back(datadir);
483 std::vector<string>::iterator iter = std::find(
inputDirs.begin(),
496 string::size_type islash = name.find(
'/');
497 string::size_type ibslash = name.find(
'\\');
502 if (name.find(
"~/") == 0) {
503 char* home = getenv(
"HOME");
505 home = getenv(
"USERPROFILE");
508 return home + name.substr(1,
npos);
513 size_t nd = dirs.size();
515 for (
size_t i = 0; i < nd; i++) {
516 inname = dirs[i] +
"/" + name;
517 std::ifstream fin(inname.c_str());
524 msg =
"\nInput file " + name
525 +
" not found in director";
526 msg += (nd == 1 ?
"y " :
"ies ");
527 for (
size_t i = 0; i < nd; i++) {
528 msg +=
"\n'" + dirs[i] +
"'";
534 msg +=
"To fix this problem, either:\n";
535 msg +=
" a) move the missing files into the local directory;\n";
536 msg +=
" b) define environment variable CANTERA_DATA to\n";
537 msg +=
" point to the directory containing the file.";
void popError()
Discard the last error message.
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.
ThreadMessages pMessenger
Current pointer to the logwriter.
virtual ~Application()
Destructor for class deletes global data.
Messages()
Constructor for the Messages class.
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 logerror(const std::string &msg)
Write an error message and quit.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
void addError(const std::string &r, const std::string &msg)
Set an error condition in the application class without throwing an exception.
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.
boost::shared_ptr< Messages > pMessages_t
Typedef for thread specific messages.
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.
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 ...
static mutex_t msg_mutex
Mutex for access to string messages.
void lock()
Set the lock for this node and all of its children.
static Unit * units()
Initialize the static Unit class.
void error(const std::string &msg)
Write an error message and quit.
static mutex_t app_mutex
Mutex for creating singletons within the application object.
Base class for exceptions thrown by Cantera classes.
void setLogger(Logger *logwriter)
Install a logger.
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.
Class to carry out messages.
std::vector< std::string > errorMessage
Current list of error messages.
static mutex_t xml_mutex
Mutex for controlling access to XML file storage.
Contains declarations for string manipulation functions within Cantera.
std::vector< std::string > errorRoutine
Current error Routine.
static mutex_t dir_mutex
Mutex for input directory access.
static void ApplicationDestroy()
Static function that destroys the application class's data.
Logger * logwriter
Current pointer to the logwriter.
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 build(std::istream &f)
Main routine to create an tree-like representation of an XML file.
void logErrors()
Prints all of the error messages using writelog.
bool stop_on_error
Current list of error messages.
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.