21 #pragma comment(lib, "advapi32")
31 #ifdef THREAD_SAFE_CANTERA
32 cthreadId_t getThisThreadId()
34 #if defined(BOOST_HAS_WINTHREADS)
35 return ::GetCurrentThreadId();
36 #elif defined(BOOST_HAS_PTHREADS)
37 return pthread_self();
71 errorMessage(r.errorMessage),
72 errorRoutine(r.errorRoutine),
78 loglevels(r.loglevels),
79 loggroups(r.loggroups)
93 errorRoutine = r.errorRoutine;
94 logwriter =
new Logger(*(r.logwriter));
98 loglevel = r.loglevel;
99 loglevels = r.loglevels;
100 loggroups = r.loggroups;
105 Application::Messages::~Messages()
108 #ifdef WITH_HTML_LOGS
117 errorMessage.push_back(msg);
118 errorRoutine.push_back(r);
123 return static_cast<int>(errorMessage.size()) ;
128 if (logwriter == _logwriter) {
131 if (logwriter != 0) {
135 logwriter = _logwriter;
140 logwriter->error(msg) ;
145 logwriter->write(msg);
150 logwriter->writeendl();
153 #ifdef WITH_HTML_LOGS
158 "HTML Logs will be removed in Cantera 2.2");
160 loglevels.push_back(loglevel);
163 if (_loglevel != -99) {
164 loglevel = _loglevel;
170 loggroups.push_back(title);
180 current = &xmllog->addChild(
"ul");
183 current = ¤t->addChild(
"li",
"<b>"+title+
"</b>");
184 current = ¤t->addChild(
"ul");
189 if (loglevel > 0 && current) {
190 current->addChild(
"li",tag+
": "+value);
196 if (loglevel > 0 && current) {
197 current->addChild(
"li",tag+
": "+
fp2str(value));
203 if (loglevel > 0 && current) {
204 current->addChild(
"li",tag+
": "+
int2str(value));
210 if (loglevel > 0 && current) {
211 current->addChild(
"li",msg);
217 if (title !=
"" && title != loggroups.back()) {
219 "\n beginLogGroup: "+ loggroups.back()+
220 "\n endLogGroup: "+title+
"\n");
224 if (loggroups.size() == 1) {
226 }
else if (loglevel > 0) {
228 "Error while ending a LogGroup. This is probably due to an unmatched"
229 " beginning and ending group");
230 current = current->parent();
232 "Error while ending a LogGroup. This is probably due to an unmatched"
233 " beginning and ending group");
234 current = current->parent();
239 loggroups.pop_back();
240 loglevel = loglevels.back();
241 loglevels.pop_back();
247 "HTML Logs will be removed in Cantera 2.2");
252 std::string::size_type idot = file.rfind(
'.');
253 std::string ext =
"";
254 std::string nm = file;
256 ext = file.substr(idot, file.size());
257 nm = file.substr(0,idot);
266 std::string fname = nm + ext;
268 while (std::ifstream(fname.c_str())) {
278 std::ofstream f(fname.c_str());
280 xmllog->root().write(f);
282 writelog(
"Log file " + fname +
" written.\n");
289 #endif // WITH_HTML_LOGS
291 #ifdef THREAD_SAFE_CANTERA
299 cthreadId_t curId = getThisThreadId() ;
300 threadMsgMap_t::iterator iter = m_threadMsgMap.find(curId) ;
301 if (iter != m_threadMsgMap.end()) {
302 return iter->second.get();
305 m_threadMsgMap.insert(std::pair< cthreadId_t, pMessages_t >(curId, pMsgs)) ;
312 cthreadId_t curId = getThisThreadId() ;
313 threadMsgMap_t::iterator iter = m_threadMsgMap.find(curId) ;
314 if (iter != m_threadMsgMap.end()) {
315 m_threadMsgMap.erase(iter) ;
318 #endif // THREAD_SAFE_CANTERA
325 m_suppress_deprecation_warnings(false),
328 #if !defined( THREAD_SAFE_CANTERA )
342 #if defined(THREAD_SAFE_CANTERA)
358 std::map<std::string, XML_Node*>::iterator pos;
360 pos->second->unlock();
376 const std::string& extra)
378 if (m_suppress_deprecation_warnings ||
warnings.count(method)) {
382 writelog(
"WARNING: '" + method +
"' is deprecated. " + extra);
388 #if defined(THREAD_SAFE_CANTERA)
397 std::string path =
"";
402 std::replace_if(path.begin(), path.end(),
403 std::bind2nd(std::equal_to<char>(),
'\\'),
'/') ;
414 string::size_type idot = path.rfind(
'.');
417 ext = path.substr(idot, path.size());
422 if (ext !=
".xml" && ext !=
".ctml") {
430 string::size_type islash = path.rfind(
'/');
432 ff = string(
"./")+path.substr(islash+1,idot-islash - 1) +
".xml";
434 ff = string(
"./")+path.substr(0,idot) +
".xml";
437 writelog(
"get_XML_File(): Expected location of xml file = " +
447 writelog(
"get_XML_File(): File, " + ff +
448 ", was previously read." +
449 " Retrieving the stored xml tree.\n");
466 std::ifstream s(ff.c_str());
474 string estring =
"cannot open "+ff+
" for reading.";
475 estring +=
"Note, this error indicates a possible configuration problem.";
493 std::map<string, XML_Node*>::iterator
496 for (; b != e; ++b) {
509 long int Application::readStringRegistryKey(
const std::string& keyName,
const std::string& valueName,
510 std::string& value,
const std::string& defaultValue)
514 long open_error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_READ, &key);
515 if (open_error != ERROR_SUCCESS) {
518 value = defaultValue;
520 DWORD bufferSize =
sizeof(buffer);
522 error = RegQueryValueEx(key, valueName.c_str(), 0, NULL, (LPBYTE) buffer, &bufferSize);
523 if (ERROR_SUCCESS == error) {
541 if (static_cast<int>(errorMessage.size()) > 0) {
543 "\n\n************************************************\n"
545 "************************************************\n\n";
546 return head+string(
"\nProcedure: ")+errorRoutine.back()
547 +string(
"\nError: ")+errorMessage.back();
549 return "<no Cantera error>";
555 int i =
static_cast<int>(errorMessage.size());
560 f <<
"************************************************" << endl;
561 f <<
" Cantera Error! " << endl;
562 f <<
"************************************************" << endl
565 for (j = 0; j < i; j++) {
567 f <<
"Procedure: " << errorRoutine[j] << endl;
568 f <<
"Error: " << errorMessage[j] << endl;
571 errorMessage.clear();
572 errorRoutine.clear();
577 int i =
static_cast<int>(errorMessage.size());
582 writelog(
"************************************************\n");
584 writelog(
"************************************************\n\n");
586 for (j = 0; j < i; j++) {
588 writelog(
string(
"Procedure: ")+ errorRoutine[j]+
" \n");
589 writelog(
string(
"Error: ")+ errorMessage[j]+
" \n");
592 errorMessage.clear();
593 errorRoutine.clear();
610 std::string installDir;
611 readStringRegistryKey(
"SOFTWARE\\Cantera\\Cantera 2.0",
612 "InstallDir", installDir,
"");
613 if (installDir !=
"") {
614 dirs.push_back(installDir +
"data");
615 dirs.push_back(installDir +
"templates");
619 const char* old_pythonpath = getenv(
"PYTHONPATH");
620 std::string pythonpath =
"PYTHONPATH=" + installDir +
"\\bin";
621 if (old_pythonpath) {
623 pythonpath.append(old_pythonpath);
625 putenv(pythonpath.c_str());
634 dirs.push_back(
"/Applications/Cantera/data");
641 if (getenv(
"CANTERA_DATA") != 0) {
642 string datadir = string(getenv(
"CANTERA_DATA"));
643 dirs.push_back(datadir);
651 string datadir = string(CANTERA_DATA);
652 dirs.push_back(datadir);
666 for (m = 0; m < n; m++) {
678 string::size_type islash = name.find(
'/');
679 string::size_type ibslash = name.find(
'\\');
685 nd =
static_cast<int>(dirs.size());
688 for (i = 0; i < nd; i++) {
689 inname = dirs[i] +
"/" + name;
690 std::ifstream fin(inname.c_str());
697 msg =
"\nInput file " + name
698 +
" not found in director";
699 msg += (nd == 1 ?
"y " :
"ies ");
700 for (i = 0; i < nd; i++) {
701 msg +=
"\n'" + dirs[i] +
"'";
707 msg +=
"To fix this problem, either:\n";
708 msg +=
" a) move the missing files into the local directory;\n";
709 msg +=
" b) define environment variable CANTERA_DATA to\n";
710 msg +=
" point to the directory containing the file.";
void popError()
Discard the last error message.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
void writelogendl()
Write an end of line character to the screen and flush output.
std::map< std::string, XML_Node * > xmlfiles
Current vector of xml file trees that have been previously parsed.
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"
void beginLogGroup(const std::string &title, int loglevel)
Create a new group for log messages.
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.
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.
#define AssertThrowMsg(expr, procedure, message)
Assertion must be true or an error is thrown.
std::string lastErrorMessage()
Retrieve the last error message in a string.
void addLogEntry(const std::string &tag, const std::string &value)
Add an entry to an HTML log file.
static mutex_t msg_mutex
Mutex for access to string messages.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
static Unit * units()
Initialize the static Unit class.
void error(const std::string &msg)
Write an error message and quit.
Classes providing support for XML data files.
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)
void write_logfile(const std::string &file)
Write the HTML log file.
XML_Node * get_XML_File(const std::string &file, int debug=0)
Return a pointer to the XML tree for a Cantera input file.
void endLogGroup(const std::string &title)
Close the current group of log messages.
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.
void write_logfile(const std::string &file)
Write the HTML log file.
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 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.
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
void close_XML_File(const std::string &file)
Close an XML File.
std::map< std::string, std::string > options
Current map of options.