247 lines
7.2 KiB
C++
247 lines
7.2 KiB
C++
/**
|
|
* @file ct2ctml.cpp
|
|
*
|
|
* $Author$
|
|
* $Revision$
|
|
* $Date$
|
|
*/
|
|
|
|
// Copyright 2001 California Institute of Technology
|
|
|
|
// turn off warnings under Windows
|
|
#ifdef WIN32
|
|
#pragma warning(disable:4786)
|
|
#pragma warning(disable:4503)
|
|
#endif
|
|
|
|
#include "ct_defs.h"
|
|
#include "ctexceptions.h"
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include "ctml.h"
|
|
|
|
using namespace Cantera;
|
|
|
|
namespace ctml {
|
|
|
|
// return the full path to the Python interpreter. Use
|
|
// environment variable PYTHON_CMD if it is set, otherwise use the
|
|
// definition PYTHON_EXE if it is defined. Failing that, return
|
|
// the string 'python'.
|
|
static string pypath() {
|
|
string s = "python";
|
|
const char* py = getenv("PYTHON_CMD");
|
|
if (py) {
|
|
s = string(py);
|
|
}
|
|
#ifdef PYTHON_EXE
|
|
else {
|
|
s = string(PYTHON_EXE);
|
|
}
|
|
#endif
|
|
return s;
|
|
}
|
|
|
|
static bool checkPython() {
|
|
time_t aclock;
|
|
time( &aclock );
|
|
string path = tmpDir() + "/.check"+int2str(aclock)+".pyw";
|
|
ofstream f(path.c_str());
|
|
if (!f) {
|
|
throw CanteraError("checkPython","cannot open "+path+" for writing");
|
|
}
|
|
f << "from Cantera import ctml_writer\n";
|
|
f.close();
|
|
int ierr = 0;
|
|
#ifdef WIN32
|
|
string cmd = "cmd /C "+pypath() + " " + path + ">> log 2>&1";
|
|
#else
|
|
string cmd = pypath() + " " + path + " &> " + tmpDir() + "/log";
|
|
#endif
|
|
try {
|
|
ierr = system(cmd.c_str());
|
|
if (ierr != 0) {
|
|
string msg;
|
|
msg = cmd +"\n\n########################################################################\n\n"
|
|
"The Cantera Python interface is required in order to process\n"
|
|
"Cantera input files, but it does not seem to be correctly installed.\n\n"
|
|
"Check that you can invoke the Python interpreter with \n"
|
|
"the command \"python\", and that typing \"from Cantera import *\" \n"
|
|
"at the Python prompt does not produce an error. If Python on your system\n"
|
|
"is invoked with some other command, set environment variable PYTHON_CMD\n"
|
|
"to the full path to the Python interpreter. \n\n"
|
|
"#########################################################################\n\n";
|
|
writelog(msg);
|
|
return false;
|
|
}
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
#ifdef WIN32
|
|
cmd = "cmd /C rm " + path;
|
|
#else
|
|
cmd = "rm -f " + path;
|
|
try {
|
|
system(cmd.c_str());
|
|
}
|
|
catch (...) { ; }
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
|
|
void ct2ctml(const char* file) {
|
|
|
|
time_t aclock;
|
|
time( &aclock );
|
|
|
|
string path = tmpDir()+"/.cttmp"+int2str(aclock)+".pyw";
|
|
ofstream f(path.c_str());
|
|
if (!f) {
|
|
throw CanteraError("ct2ctml","cannot open "+path+" for writing.");
|
|
}
|
|
f << "from ctml_writer import *\n"
|
|
<< "import sys, os, os.path\n"
|
|
<< "file = \"" << file << "\"\n"
|
|
<< "base = os.path.basename(file)\n"
|
|
<< "root, ext = os.path.splitext(base)\n"
|
|
<< "dataset(root)\n"
|
|
<< "execfile(file)\n"
|
|
<< "write()\n";
|
|
f.close();
|
|
#ifdef WIN32
|
|
string cmd = pypath() + " " + path + "> ct2ctml.log 2>&1";
|
|
#else
|
|
string cmd = pypath() + " " + path + " &> ct2ctml.log";
|
|
#endif
|
|
#ifdef DEBUG_PATHS
|
|
cout << "ct2ctml: executing the command " << cmd << endl;
|
|
#endif
|
|
int ierr = 0;
|
|
try {
|
|
ierr = system(cmd.c_str());
|
|
}
|
|
catch (...) {
|
|
ierr = -10;
|
|
}
|
|
|
|
/*
|
|
* HKM -> This next section may seem a bit weird. However,
|
|
* it is in response to an issue that arises when
|
|
* running cantera with cygwin, using cygwin's
|
|
* python intepreter. Basically, the xml file is
|
|
* written to the local directory by the last
|
|
* system command. Then, the xml file is read
|
|
* immediately after by an ifstream() c++
|
|
* command. Unfortunately, it seems that the
|
|
* directory info is not being synched fast enough
|
|
* so that the ifstream() read fails, even
|
|
* though the file is actually there. Putting in a
|
|
* sleep system call here fixes this problem. Also,
|
|
* having the xml file pre-existing fixes the
|
|
* problem as well. There may be more direct ways
|
|
* to fix this bug; however, I am not aware of them.
|
|
*/
|
|
#if defined(CYGWIN)
|
|
#ifdef DEBUG_PATHS
|
|
cout << "sleeping for 3 secs" << endl;
|
|
#endif
|
|
cmd = "sleep 3";
|
|
try {
|
|
ierr = system(cmd.c_str());
|
|
}
|
|
catch (...) {
|
|
ierr = -10;
|
|
}
|
|
#endif
|
|
|
|
try {
|
|
char ch=0;
|
|
string s = "";
|
|
ifstream ferr("ct2ctml.log");
|
|
if (ferr) {
|
|
while (!ferr.eof()) {
|
|
ferr.get(ch);
|
|
s += ch;
|
|
if (ch == '\n') {
|
|
writelog(s);
|
|
s = "";
|
|
}
|
|
}
|
|
ferr.close();
|
|
}
|
|
}
|
|
catch (...) {
|
|
;
|
|
}
|
|
if (ierr != 0) {
|
|
string msg = cmd;
|
|
bool pyok = checkPython();
|
|
if (!pyok)
|
|
msg += "\nError in Python installation.";
|
|
else
|
|
msg += "\nCheck error messages above for syntax errors.";
|
|
throw CanteraError("ct2ctml",
|
|
"could not convert input file to CTML\n "
|
|
"command line was: " + msg);
|
|
}
|
|
#ifndef DEBUG_PATHS
|
|
#ifdef WIN32
|
|
cmd = "cmd /C rm " + path;
|
|
#else
|
|
cmd = "rm -f " + path;
|
|
try {
|
|
system(cmd.c_str());
|
|
}
|
|
catch (...) { ; }
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
/**
|
|
* Get an CTML tree from a file, possibly preprocessing the file
|
|
* first.
|
|
*/
|
|
void get_CTML_Tree(XML_Node* rootPtr, string file) {
|
|
string ff, ext = "";
|
|
|
|
// find the input file on the Cantera search path
|
|
string inname = findInputFile(file);
|
|
#ifdef DEBUG_PATHS
|
|
cout <<"Found file: " << inname << endl;
|
|
#endif
|
|
if (inname == "")
|
|
throw CanteraError("get_CTML_tree", "file "+file+" not found");
|
|
|
|
/**
|
|
* Check whether or not the file is XML. If not, it will be first
|
|
* processed with the preprocessor.
|
|
*/
|
|
string::size_type idot = inname.rfind('.');
|
|
if (idot != string::npos) {
|
|
ext = inname.substr(idot, inname.size());
|
|
}
|
|
if (ext != ".xml" && ext != ".ctml") {
|
|
ct2ctml(inname.c_str());
|
|
ff = inname.substr(0,idot) + ".xml";
|
|
}
|
|
else {
|
|
ff = inname;
|
|
}
|
|
#ifdef DEBUG_PATHS
|
|
cout << "Attempting to parse xml file " << ff << endl;
|
|
#endif
|
|
ifstream fin(ff.c_str());
|
|
if (!fin) {
|
|
throw
|
|
CanteraError("get_CTML_tree",
|
|
"XML file " + ff + " not found");
|
|
}
|
|
rootPtr->build(fin);
|
|
fin.close();
|
|
}
|
|
}
|