Added a function called appdelete(), which deletes all global

data malloced by Cantera. With this call added to applications,
Cantera passes the leak check from the valgrind application.
(Well there is some squirrely behavior associated with either
valgrind, linux, or the stl implementation, but it's not
Cantera's fault).

I also changed get_XML_File to store the absolute pathname
in the map, so that the same XML tree isn't deleted twice.
Lookups are always done wrt absolute pathnames.
This commit is contained in:
Harry Moffat 2003-09-03 18:45:06 +00:00
parent 1c51cc7f78
commit 6f190b568d
2 changed files with 72 additions and 30 deletions

View file

@ -44,6 +44,9 @@ namespace Cantera {
/// Add a directory to the search path
void addDirectory(string dir);
/// Delete the application singly defined information
void appdelete();
// Write a message (deprecated; use writelog)
//void write(const string& msg);

View file

@ -19,6 +19,7 @@
#include "units.h"
#include "xml.h"
#include "ctml.h"
#include "SpeciesThermoFactory.h"
#ifndef WIN32
#include "ctdir.h"
@ -41,7 +42,13 @@ namespace Cantera {
public:
Application() : linelen(0), stop_on_error(false),
tmp_dir("/tmp") {}
virtual ~Application(){}
virtual ~Application() {
map<string, XML_Node*>::iterator pos;
for (pos = xmlfiles.begin(); pos != xmlfiles.end(); ++pos) {
delete pos->second;
pos->second = 0;
}
}
vector<string> inputDirs;
vector<string> errorMessage;
vector<string> warning;
@ -49,8 +56,6 @@ namespace Cantera {
string msglog;
size_t linelen;
bool stop_on_error;
//bool write_log_to_cout;
//bool matlab;
map<string, string> options;
string tmp_dir;
map<string, XML_Node*> xmlfiles;
@ -69,6 +74,20 @@ namespace Cantera {
if (__app == 0) __app = new Application;
}
/**
* This function deletes the global information. It should be called
* at the end of the application, especially if leak checking is
* to be done.
*/
void appdelete() {
if (__app) {
delete __app;
__app = 0;
}
SpeciesThermoFactory::deleteFactory();
Unit::deleteUnit();
}
Application* app() {
if (__app == 0) {
__app = new Application;
@ -78,50 +97,69 @@ namespace Cantera {
}
XML_Node* get_XML_File(string file) {
if (app()->xmlfiles.find(file)
string path = findInputFile(file);
string ff = path;
if (app()->xmlfiles.find(path)
== app()->xmlfiles.end()) {
string path = findInputFile(file);
/*
* Check whether or not the file is XML. If not, it will
* be first processed with the preprocessor.
* be first processed with the preprocessor. We determine
* whether it is an XML file by looking at the file extension.
*/
string::size_type idot = path.rfind('.');
string ext, ff;
string ext;
if (idot != string::npos) {
ext = path.substr(idot, path.size());
}
if (ext != ".xml" && ext != ".ctml") {
ctml::ct2ctml(path.c_str());
string::size_type islash = path.rfind('/');
if (islash != string::npos)
ff = string("./")+path.substr(islash+1,idot-islash - 1) + ".xml";
else
ff = string("./")+path.substr(0,idot) + ".xml";
/*
* We will assume that we are trying to open a cti file.
* First, determine the name of the xml file, ff, derived from
* the cti file.
*/
string::size_type islash = path.rfind('/');
if (islash != string::npos)
ff = string("./")+path.substr(islash+1,idot-islash - 1) + ".xml";
else
ff = string("./")+path.substr(0,idot) + ".xml";
/*
* Do a search of the existing XML trees to determine if we have
* already processed this file. If we have, return a pointer to
* the processed xml tree.
*/
if (app()->xmlfiles.find(ff) != app()->xmlfiles.end()) {
return __app->xmlfiles[ff];
}
/*
* Ok, we didn't find the processed XML tree. Do the conversion
* to xml, possibly overwriting the file, ff, in the process.
*/
ctml::ct2ctml(path.c_str());
}
else {
ff = path;
}
/*
* Take the XML file ff, open it, and process it, creating an
* XML tree, and then adding an entry in the map. We will store
* the absolute pathname as the key for this map.
*/
ifstream s(ff.c_str());
XML_Node* x = new XML_Node("doc");
if (s) {
x->build(s);
__app->xmlfiles[file] = x;
__app->xmlfiles[ff] = x;
x->build(s);
__app->xmlfiles[ff] = x;
}
else
throw CanteraError("get_XML_File","cannot open "+ff+" for reading.");
/*
* Add the built XML Tree to the map, xmlfiles.
* It stores the pointer to the tree, with the
* key being the name of the file.
*
* HKM Note: shouldn't the key be the full pathname of
* the file, i.e., ff?
*/
else {
throw CanteraError("get_XML_File","cannot open "+ff+" for reading.");
}
}
return __app->xmlfiles[file];
/*
* Return the XML node pointer. At this point, we are sure that the
* lookup operation in the return statement will return a valid
* pointer.
*/
return __app->xmlfiles[ff];
}
void close_XML_File(string file) {
@ -156,7 +194,8 @@ namespace Cantera {
string lastErrorMessage() {
appinit();
if (nErrors() > 0)
return "\nProcedure: "+__app->errorRoutine.back()+"\nError: "+__app->errorMessage.back();
return "\nProcedure: "+__app->errorRoutine.back()
+"\nError: "+__app->errorMessage.back();
else
return "<no Cantera error>";
}