From 1de1096149dcf6327f5a0e2391b2db21f8634023 Mon Sep 17 00:00:00 2001 From: Hugo Date: Thu, 31 Aug 2017 13:36:47 +0200 Subject: [PATCH] Merge pull request #368 from Anatoscope/sofapython-forward-argv [SofaPython/core] forward sys.argv to python scripts (cherry picked from commit da84f5f5d2cf2f7bd2435ab7a3d8f74d64ed55c7) # Conflicts: # SofaKernel/framework/sofa/helper/ArgumentParser.cpp --- .../framework/sofa/helper/ArgumentParser.cpp | 21 +++- .../framework/sofa/helper/ArgumentParser.h | 9 +- .../plugins/SofaPython/PythonEnvironment.cpp | 99 ++++++++++--------- .../plugins/SofaPython/SceneLoaderPY.cpp | 3 +- 4 files changed, 79 insertions(+), 53 deletions(-) diff --git a/SofaKernel/framework/sofa/helper/ArgumentParser.cpp b/SofaKernel/framework/sofa/helper/ArgumentParser.cpp index 609c30e4da5..c049905fd29 100644 --- a/SofaKernel/framework/sofa/helper/ArgumentParser.cpp +++ b/SofaKernel/framework/sofa/helper/ArgumentParser.cpp @@ -34,6 +34,8 @@ namespace helper typedef std::istringstream istrstream; +ArgumentParser::extra_type ArgumentParser::extra; + ArgumentBase::ArgumentBase(char s, string l, string h, bool m) : shortName(s) , longName(l) @@ -86,9 +88,7 @@ ArgumentParser::~ArgumentParser() */ void ArgumentParser::operator () ( int argc, char** argv ) { - std::list str; - for (int i=1; i str(argv + 1, argv + argc); (*this)(str); } @@ -97,6 +97,9 @@ void ArgumentParser::operator () ( std::list str ) string shHelp("-"); shHelp.push_back( helpShortName ); string lgHelp("--"); lgHelp.append( helpLongName ); string name; + + static const std::string extra_opt = "--argv"; + while( !str.empty() ) { name = str.front(); @@ -109,13 +112,19 @@ void ArgumentParser::operator () ( std::list str ) if( name == shHelp || name == lgHelp ) { if( globalHelp.size()>0 ) std::cout<< globalHelp <print(); std::cout << std::noboolalpha; + + std::cout << "--argv [...]\t" << "forward extra args to the python interpreter" << std::endl; + if( files ) std::cout << "others: file names" << std::endl; + + exit(EXIT_FAILURE); } @@ -132,6 +141,12 @@ void ArgumentParser::operator () ( std::list str ) str.pop_front(); } + // extra args + else if( name == extra_opt ) { + extra = extra_type(str.begin(), str.end()); + return; + } + // long name else if( name.length() > 1 && name[0]=='-' && name[1]=='-' ) { diff --git a/SofaKernel/framework/sofa/helper/ArgumentParser.h b/SofaKernel/framework/sofa/helper/ArgumentParser.h index fac8d0ad5a3..64bdb5d6a2d 100644 --- a/SofaKernel/framework/sofa/helper/ArgumentParser.h +++ b/SofaKernel/framework/sofa/helper/ArgumentParser.h @@ -251,13 +251,19 @@ class SOFA_HELPER_API ArgumentParser /// Set of remaining file std::vector* files; + /// extra args appearing after --argv + using extra_type = std::vector; + static extra_type extra; + // help stuff string globalHelp; ///< Overall presentation char helpShortName; ///< short name for help string helpLongName; ///< long name for help public: - + /** last parsed extra arguments */ + static const extra_type& extra_args() { return extra; } + /// Constructor using a global help string ArgumentParser( const string& helpstr="", char hlpShrt='h', const string& hlpLng="help" ); @@ -349,6 +355,7 @@ class SOFA_HELPER_API ArgumentParser return (*this); } + /** Parse a command line \param argc number of arguments + 1, as usual in C \param argv arguments diff --git a/applications/plugins/SofaPython/PythonEnvironment.cpp b/applications/plugins/SofaPython/PythonEnvironment.cpp index 03950f1b769..71a392998d7 100644 --- a/applications/plugins/SofaPython/PythonEnvironment.cpp +++ b/applications/plugins/SofaPython/PythonEnvironment.cpp @@ -289,62 +289,65 @@ helper::logging::FileInfo::SPtr PythonEnvironment::getPythonCallingPointAsFileIn return SOFA_FILE_INFO_COPIED_FROM("undefined", -1); } -bool PythonEnvironment::runFile( const char *filename, const std::vector& arguments) -{ - std::string dir = sofa::helper::system::SetDirectory::GetParentDir(filename); - std::string bareFilename = sofa::helper::system::SetDirectory::GetFileNameWithoutExtension(filename); - - if(!arguments.empty()) - { - char**argv = new char*[arguments.size()+1]; - argv[0] = new char[bareFilename.size()+1]; - strcpy( argv[0], bareFilename.c_str() ); - for( size_t i=0 ; i& arguments) { + const std::string dir = sofa::helper::system::SetDirectory::GetParentDir(filename); + + // pro-tip: FileNameWithoutExtension == basename + const std::string basename = sofa::helper::system::SetDirectory::GetFileNameWithoutExtension(filename); + + // setup sys.argv if needed + if(!arguments.empty() ) { + std::vector argv; + argv.push_back(basename.c_str()); + + for(const std::string& arg : arguments) { + argv.push_back(arg.c_str()); } - - Py_SetProgramName(argv[0]); // TODO check what it is doing exactly - PySys_SetArgv(arguments.size()+1, argv); - - for( size_t i=0 ; i +#include #include #include @@ -83,7 +84,7 @@ void SceneLoaderPY::getExtensionList(ExtensionList* list) sofa::simulation::Node::SPtr SceneLoaderPY::load(const char *filename) { sofa::simulation::Node::SPtr root; - loadSceneWithArguments(filename, {}, &root); + loadSceneWithArguments(filename, helper::ArgumentParser::extra_args(), &root); return root; }