I have a C ++ program that provides a Python interface for executing embedded Python scripts for users.
The user inserts the path to run the Python script and command line arguments. Then the script is executed through
boost::python::exec_file(filename, main_globals, main_globals)
To pass Python script command line arguments, we need to set them via the Python C-API function
PySys_SetArgv(int args, char** argv)
before calling exec_file()
.
But for this, you need to tokenize the user line containing the command line arguments to get a list of arguments, and then pass them back to the Python interpreter via PySys_SetArgv
. And this is more than just a waste of time, because in this way the main C ++ program should take responsibility for tokenizing the command line, without knowing the logic behind, which is determined only by the user script.
The metacode will have a much more pleasant and understandable approach:
string command_line_args = '-v -p "filename" -t="anotherfile" --list="["a", "b"]" --myFunnyOpt' exec_file( filename, command_line_args, ...)
I spent hours looking at the Boost documentation and the Python C-API, but I did not find anything useful. Do you know if there is a way to achieve this, i.e. Pass a whole line of command line arguments to an inline Python script from C ++?
Update:
As Steve suggested in the comments below, I solved my problem by denoting the input line by following https://stackoverflow.com/a/146996/...
In my case, I used:
// defining the separators std::string escape_char = "\\"; // the escape character std::string sep_char = " "; // empty space as separator std::string quote_char = ""; // empty string --> we don't want a quote char' boost::escaped_list_separator<char> sep( escape_char, sep_char, quote_char );
because I wanted to be able to parse tuples containing strings, for example:
'--option-two=("A", "B")'
and if you use:
escaped_list_separator<char> sep('\\', ' ', '"');
as in the original message, you are not getting correctly marked lines.