Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream input to ctml_writer to avoid command line length limits #430

Merged
merged 1 commit into from
Feb 14, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 15 additions & 69 deletions src/base/ct2ctml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

using namespace std;
Expand Down Expand Up @@ -82,14 +80,6 @@ void ct2ctml(const char* file, const int debug)
static std::string call_ctml_writer(const std::string& text, bool isfile)
{
std::string file, arg;
bool temp_file_created = false;
std::string temp_cti_file_name = std::tmpnam(nullptr);

if (temp_cti_file_name.find('\\') == 0) {
// Some versions of MinGW give paths in the root directory. Using the
// current directory is more likely to succeed.
temp_cti_file_name = "." + temp_cti_file_name;
}

if (isfile) {
file = text;
Expand All @@ -99,44 +89,6 @@ static std::string call_ctml_writer(const std::string& text, bool isfile)
arg = "text=r'''" + text + "'''";
}

// If the user wants to convert a mechanism using a text passed via the
// source="""..."""
// argument in python, then we have to make sure that it is short enough
// to fit in the command line when routed to python as:
// python -c ...
// statement downstream in the code

// So, check the max size of a string that can be passed on the command line
// This is OS Specific. *nix systems have the sysconf() function that tells
// us the largest argument we can pass. Since such a function does not exist
// for Windows, we set a safe limit of 32 kB

#ifdef _WIN32
long int max_argv_size = 32768;
#else
long int max_argv_size = sysconf(_SC_ARG_MAX);
#endif

if (text.size() > static_cast<size_t>(max_argv_size) - 500) {
// If the file is too big to be passed as a command line argument later
// in the file, then create a temporary file and execute this function
// as though an input file was specified as the source.
// We assume the text passed + 500 chars = total size of argv

ofstream temp_cti_file(temp_cti_file_name);

if (temp_cti_file) {
temp_cti_file << text;
file = temp_cti_file_name;
arg = "r'" + file + "'";
temp_file_created = true;
} else {
// If we are here, then a temp file could not be created
throw CanteraError("call_ctml_writer", "Very long source argument. "
"Error creating temporary file '{}'", temp_cti_file_name);
}
}

#ifdef HAS_NO_PYTHON
//! Section to bomb out if python is not present in the computation
//! environment.
Expand All @@ -151,21 +103,23 @@ static std::string call_ctml_writer(const std::string& text, bool isfile)
exec_stream_t python;
python.set_wait_timeout(exec_stream_t::s_all, 1800000); // 30 minutes
stringstream output_stream, error_stream;
std::vector<string> args;
args.push_back("-c");
python.start(pypath(), "");
ostream& pyin = python.in();

args.push_back(
"from __future__ import print_function\n"
"import sys\n"
"try:\n"
" from cantera import ctml_writer\n"
"except ImportError:\n"
" print('sys.path: ' + repr(sys.path) + '\\n', file=sys.stderr)\n"
" raise\n"
"ctml_writer.convert(" + arg + ", outName='STDOUT')\n"
"sys.exit(0)\n");
pyin << "from __future__ import print_function\n"
"if True:\n"
" import sys\n"
" try:\n"
" from cantera import ctml_writer\n"
" except ImportError:\n"
" print('sys.path: ' + repr(sys.path) + '\\n', file=sys.stderr)\n"
" raise\n"
" ctml_writer.convert(";
pyin << arg << ", outName='STDOUT')\n";
pyin << " sys.exit(0)\n\n";
pyin << "sys.exit(7)\n";

python.start(pypath(), args.begin(), args.end());
python.close_in();
std::string line;

while (python.out().good()) {
Expand Down Expand Up @@ -221,14 +175,6 @@ static std::string call_ctml_writer(const std::string& text, bool isfile)
writelog(message.str());
}

if (temp_file_created) {
// A temp file was created and has to be removed
bool status = std::remove(temp_cti_file_name.c_str());
if (status) {
writelog("WARNING: Error removing tmp file {}\n", temp_cti_file_name);
}
}

return python_output;
}

Expand Down