From 1714b72bfc54026dacda2fc65cedd4a418f67995 Mon Sep 17 00:00:00 2001 From: Cyrille Valladeau <cyrille.valladeau@c-s.fr> Date: Fri, 2 Sep 2011 11:07:23 +0200 Subject: [PATCH] ENH: command line in progress --- Code/Core/otbWrapperNumericalParameter.h | 5 + .../otbWrapperCommandLineParser.cxx | 374 ++++++++++++------ .../CommandLine/otbWrapperCommandLineParser.h | 28 +- .../otbWrapperCommandLineParserTests.cxx | 27 +- 4 files changed, 303 insertions(+), 131 deletions(-) diff --git a/Code/Core/otbWrapperNumericalParameter.h b/Code/Core/otbWrapperNumericalParameter.h index 5545434bcf..6c99277d12 100644 --- a/Code/Core/otbWrapperNumericalParameter.h +++ b/Code/Core/otbWrapperNumericalParameter.h @@ -59,6 +59,11 @@ public: m_Value = value; } + void SetValue( const std::string & value ) + { + m_Value = static_cast<ScalarType>(atof(value.c_str())); + } + /** Get the value */ ScalarType GetValue() const { diff --git a/Code/Wrappers/CommandLine/otbWrapperCommandLineParser.cxx b/Code/Wrappers/CommandLine/otbWrapperCommandLineParser.cxx index 92e2ebfab8..7728dbe0a3 100644 --- a/Code/Wrappers/CommandLine/otbWrapperCommandLineParser.cxx +++ b/Code/Wrappers/CommandLine/otbWrapperCommandLineParser.cxx @@ -17,6 +17,7 @@ =========================================================================*/ #include "otbWrapperCommandLineParser.h" +// Single value parameter #include "otbWrapperChoiceParameter.h" #include "otbWrapperDirectoryParameter.h" #include "otbWrapperEmptyParameter.h" @@ -29,7 +30,10 @@ #include "otbWrapperOutputVectorDataParameter.h" #include "otbWrapperRadiusParameter.h" #include "otbWrapperStringParameter.h" - +// List value parameter +#include "otbWrapperOutputImageListParameter.h" +#include "otbWrapperInputImageListParameter.h" +#include "otbWrapperStringListParameter.h" //#include "otbWrapperParameterGroup.h" @@ -106,49 +110,27 @@ CommandLineParser::CheckPath( const char * exp ) return NOMODULEPATH; } - - std::string expFromPath = std::string(exp).substr(found+m_PathKey.size(), std::string(exp).size()); - std::string tempModPath = expFromPath; - if( expFromPath.find("--") != std::string::npos) - { - tempModPath = expFromPath.substr( 0, expFromPath.find_first_of("--")-1); - } + std::vector<itksys::String> pathAttribut = GetAttribut(m_PathKey, std::string(exp)); - if( tempModPath.size() == 0 ) + if( pathAttribut.size() == 0 ) { return NOMODULEPATH; } - else - { - std::vector<itksys::String> spaceSplittedModulePath = itksys::SystemTools::SplitString(tempModPath.substr(1, tempModPath.size()).c_str(), ' ', false); - for(unsigned int i=0; i<spaceSplittedModulePath.size(); i++) - { - if( spaceSplittedModulePath[i] == " ") - { - spaceSplittedModulePath.erase(spaceSplittedModulePath.begin()+i); - i--; - } - } - if( spaceSplittedModulePath.size() == 0 ) + + std::string pathlist; + for( unsigned i=0; i<pathAttribut.size(); i++) + { + std::string fullPath = itksys::SystemTools::CollapseFullPath(pathAttribut[i].c_str()); + if( !itksys::SystemTools::FileIsDirectory(fullPath.c_str()) ) { - return NOMODULEPATH; + return INVALIDMODULEPATH; } - - std::string pathlist; - for( unsigned i=0; i<spaceSplittedModulePath.size(); i++) - { - std::string fullPath = itksys::SystemTools::CollapseFullPath(spaceSplittedModulePath[i].c_str()); - if( !itksys::SystemTools::FileIsDirectory(fullPath.c_str()) ) - { - return INVALIDMODULEPATH; - } - pathlist.append(fullPath); - pathlist.append(":"); - } - - m_Path = pathlist; + pathlist.append(fullPath); + pathlist.append(":"); } - + + m_Path = pathlist; + return OK; } @@ -158,7 +140,7 @@ CommandLineParser::LoadPath() // Load the path in the environment std::string specificEnv("ITK_AUTOLOAD_PATH="); specificEnv.append(m_Path); - std::cout<<specificEnv<<std::endl; + // do NOT use putenv() directly, since the string memory must be managed carefully itksys::SystemTools::PutEnv(specificEnv.c_str()); // Reload factories to take into account new path @@ -199,7 +181,6 @@ CommandLineParser::CheckModuleName( const char * exp ) { if( spaceSplittedExp[1].substr(0,2) != "--" ) { - std::cout<<"Multiple at level 1"<<std::endl; return MULTIPLEMODULENAME; } } @@ -225,52 +206,67 @@ CommandLineParser::CheckModuleName( const char * exp ) } else { - /* - std::string expFromModule = std::string(exp).substr(found+m_ModuleNameKey.size(), std::string(exp).size()); - std::string tempModName = expFromModule; - if( expFromModule.find("--") != std::string::npos) + std::vector<itksys::String> moduleNameAttribut = GetAttribut(m_ModuleNameKey, std::string(exp)); + + if( moduleNameAttribut.size() == 0 ) { - tempModName = expFromModule.substr( 0, expFromModule.find_first_of("--")-1); + return NOMODULENAME; } - - if( tempModName.size() == 0 ) + if( moduleNameAttribut.size() > 1 ) { - return NOMODULENAME; + return MULTIPLEMODULENAME; } - else + if(reg.find(moduleNameAttribut[0])) { - std::vector<itksys::String> spaceSplittedModuleName = itksys::SystemTools::SplitString(tempModName.substr(1, tempModName.size()).c_str(), ' ', false); - for(unsigned int i=0; i<spaceSplittedModuleName.size(); i++) - { - if( spaceSplittedModuleName[i] == " ") - { - spaceSplittedModuleName.erase(spaceSplittedModuleName.begin()+i); - i--; - } - } - */ - std::vector<itksys::String> moduleNameAttribut = GetAttribut(m_ModuleNameKey, std::string(exp)); + return INVALIDMODULENAME; + } + + m_ModuleName = moduleNameAttribut[0]; + } + } - if( moduleNameAttribut.size() == 0 ) - { - return NOMODULENAME; - } - if( moduleNameAttribut.size() > 1 ) - { - return MULTIPLEMODULENAME; - } - if(reg.find(moduleNameAttribut[0])) - { - return INVALIDMODULENAME; - } - - m_ModuleName = moduleNameAttribut[0]; - + return OK; +} + + +std::vector<itksys::String> +CommandLineParser::GetAttribut( const std::string & key, const std::string & exp ) +{ + std::size_t found = std::string(exp).find(key); + if( found == std::string::npos ) + { + itkExceptionMacro("No key \""<<key<<"\" found in \""<<exp<<"\"."); + } + + std::string expFromKey = std::string(exp).substr(found+key.size(), std::string(exp).size()); + std::string tempModKey = expFromKey; + // remove other key in the string if there's any + if( expFromKey.find("--") != std::string::npos) + { + tempModKey = expFromKey.substr( 0, expFromKey.find("--")-1); + } + + std::vector<itksys::String> spaceSplitted = itksys::SystemTools::SplitString(tempModKey.substr(1, tempModKey.size()).c_str(), ' ', false); + // Remove " " string element + for(unsigned int i=0; i<spaceSplitted.size(); i++) + { + if( spaceSplitted[i] == " ") + { + spaceSplitted.erase(spaceSplitted.begin()+i); + i--; } } + // Removespace at the begining of the string + for(unsigned int i=0; i<spaceSplitted.size(); i++) + { + while( spaceSplitted[i][0] == ' ' ) + { + spaceSplitted[i] = spaceSplitted[i].substr(1, spaceSplitted[i].size()); + } + } - return OK; + return spaceSplitted; } @@ -281,11 +277,6 @@ CommandLineParser::LoadApplication( const std::string & moduleName ) m_Application = ApplicationRegistry::CreateApplication(moduleName); - for(unsigned int i=0; i<ApplicationRegistry::GetAvailableApplications().size(); i++) - std::cout<<ApplicationRegistry::GetAvailableApplications()[i]<<std::endl; - - std::cout<<moduleName<<std::endl; - if (m_Application.IsNull()) { std::cout << "Could not find application \"" << moduleName <<"\""<< std::endl; @@ -297,14 +288,14 @@ CommandLineParser::LoadApplication( const std::string & moduleName ) } -bool -CommandLineParser::CheckApplicationArgument( const std::string & exp ) +CommandLineParser::ParseResultType +CommandLineParser::ParseApplicationArgument( const std::string & exp ) { - return this->CheckApplicationArgument( exp.c_str() ); + return this->ParseApplicationArgument( exp.c_str() ); } -bool -CommandLineParser::CheckApplicationArgument( const char * exp ) +CommandLineParser::ParseResultType +CommandLineParser::ParseApplicationArgument( const char * exp ) { if( m_Application.IsNull() ) { @@ -318,67 +309,214 @@ CommandLineParser::CheckApplicationArgument( const char * exp ) for( unsigned int i=0; i<nbOfParam; i++ ) { - if( paramGr->GetParameterByIndex(i)->GetMandatory() == true ) + std::cout<<paramGr->GetParameterByIndex(i)->GetKey()<<std::endl; + std::vector<itksys::String> values; + Parameter::Pointer param = paramGr->GetParameterByIndex(i); + // Check if mandatory parameter are present and have value + if( param->GetMandatory() == true ) { - // Check if the attribut is in the expression - std::size_t found = std::string(exp).find(paramGr->GetParameterByIndex(i)->GetKey()); + std::size_t found = std::string(exp).find(param->GetKey()); if( found == std::string::npos ) { - std::cout<<paramGr->GetParameterByIndex(i)->GetKey()<<std::endl; - return MISSINGMANDATORYATTRIBUT; + std::cout<<param->GetKey()<<std::endl; + return MISSINGMANDATORYPARAMETER; + } + values = this->GetAttribut( std::string("--").append(param->GetKey()), std::string(exp)); + if( values.size() == 0 ) + { + std::cout<<"No param for... "<<param->GetKey()<<std::endl; + return MISSINGPARAMETERVALUE; } } + // Check if non mandatory parameter have values + else + { + std::size_t found = std::string(exp).find(param->GetKey()); + if( found != std::string::npos ) + { + values = this->GetAttribut( std::string("--").append(param->GetKey()), std::string(exp)); + if( values.size() == 0 ) + { + std::cout<<"No param for... "<<param->GetKey()<<std::endl; + return MISSINGPARAMETERVALUE; + } + } + } + + // Cast into std::vecto<std::string> + std::vector<std::string> svValues; + for( unsigned int j=0; j<values.size(); j++) + { + svValues.push_back(values[j]); + } + + // List values parameter case + if( this->CanCreateParameter<InputImageListParameter>(param) == true ) + { + this->SetFromFileNameToParameter<InputImageListParameter>( param, svValues ); + } + else if( this->CanCreateParameter<OutputImageListParameter>(param) == true ) + { + this->SetFileNameToParameter<OutputImageListParameter>( param, svValues); + } + else if( this->CanCreateParameter<StringListParameter>(param) == true ) + { + this->SetValueToParameter<StringListParameter>( param, svValues ); + } + else if( svValues.size() != 1) + { + return INVALIDNUMBEROFVALUE; + } + + // Single value parameter + if( this->CanCreateParameter<ChoiceParameter>(param) == true ) + { + this->SetValueToParameter<ChoiceParameter>( param, svValues[0] ); + } + else if( this->CanCreateParameter<FloatParameter>(param) == true ) + { + this->SetValueToParameter<FloatParameter>( param, svValues[0] ); + } + else if( this->CanCreateParameter<IntParameter>(param) == true ) + { + this->SetValueToParameter<IntParameter>( param, svValues[0] ); + } + else if( this->CanCreateParameter<RadiusParameter>(param) == true ) + { + this->SetValueToParameter<RadiusParameter>( param, svValues[0] ); + } + else if( this->CanCreateParameter<DirectoryParameter>(param) == true ) + { + this->SetValueToParameter<DirectoryParameter>(param, svValues[0]); + } + else if( this->CanCreateParameter<StringParameter>(param) == true ) + { + this->SetValueToParameter<StringParameter>( param, svValues[0] ); + } + else if( this->CanCreateParameter<FilenameParameter>(param) == true ) + { + this->SetValueToParameter<FilenameParameter>(param, svValues[0]); + } + else if( this->CanCreateParameter<InputComplexImageParameter>(param) == true ) + { + this->SetFromFileNameToParameter<InputComplexImageParameter>(param, svValues[0]); + } + else if( this->CanCreateParameter<InputImageParameter>(param) == true ) + { + this->SetFromFileNameToParameter<InputImageParameter>(param, svValues[0]); + } + else if( this->CanCreateParameter<InputVectorDataParameter>(param) == true ) + { + this->SetFromFileNameToParameter<InputVectorDataParameter>(param, svValues[0]); + } + else if( this->CanCreateParameter<OutputImageParameter>(param) == true ) + { + this->SetFileNameToParameter<OutputImageParameter>(param, svValues[0]); + } + else if( this->CanCreateParameter<OutputVectorDataParameter>(param) == true ) + { + this->SetFileNameToParameter<OutputVectorDataParameter>(param, svValues[0]); + } + else if( this->CanCreateParameter<EmptyParameter>(param) == true ) + { + if( svValues[0] == "1" || svValues[0] == "true") + { + dynamic_cast<EmptyParameter *>(param.GetPointer())->SetActive(true); + } + else if( svValues[0] == "0" || svValues[0] == "false") + { + dynamic_cast<EmptyParameter *>(param.GetPointer())->SetActive(false); + } + else + { + return WRONGPARAMETERVALUE; + } + } } // Other return OK; } -std::vector<itksys::String> -CommandLineParser::GetAttribut( const std::string & key, const std::string & exp ) + + +template <class TParameterType> +void +CommandLineParser::SetValueToParameter(Parameter * param, const std::string & val ) { - std::size_t found = std::string(exp).find(key); - if( found == std::string::npos ) + if( !this->CanCreateParameter<TParameterType>( param ) ) { - itkExceptionMacro("No key \""<<key<<"\" found in \""<<exp<<"\"."); + itkExceptionMacro("Impossible cast to add value to the parameter "<<param->GetKey()<<"."); } - std::string expFromKey = std::string(exp).substr(found+key.size(), std::string(exp).size()); - std::string tempModKey = expFromKey; - // remove other key in the string if there's any - if( expFromKey.find("--") != std::string::npos) + dynamic_cast<TParameterType *>(param)->SetValue( val ); +} + +template <class TParameterType> +void +CommandLineParser::SetValueToParameter(Parameter * param, const std::vector<std::string> & val ) +{ + if( !this->CanCreateParameter<TParameterType>( param ) ) { - tempModKey = expFromKey.substr( 0, expFromKey.find("--")-1); + itkExceptionMacro("Impossible cast to add value to the parameter "<<param->GetKey()<<"."); } + + dynamic_cast<TParameterType *>(param)->SetValue( val ); +} - std::vector<itksys::String> spaceSplitted = itksys::SystemTools::SplitString(tempModKey.substr(1, tempModKey.size()).c_str(), ' ', false); - // Remove " " string element - for(unsigned int i=0; i<spaceSplitted.size(); i++) +template <class TParameterType> +void +CommandLineParser::SetFileNameToParameter(Parameter * param, const std::string & val ) +{ + if( !this->CanCreateParameter<TParameterType>( param ) ) { - std::cout<<spaceSplitted[i]<<std::endl; - if( spaceSplitted[i] == " ") - { - spaceSplitted.erase(spaceSplitted.begin()+i); - i--; - } + itkExceptionMacro("Impossible cast to add value to the parameter "<<param->GetKey()<<"."); } + + dynamic_cast<TParameterType *>(param)->SetFileName( val ); +} - // Removespace at the begining of the string - for(unsigned int i=0; i<spaceSplitted.size(); i++) +template <class TParameterType> +void +CommandLineParser::SetFileNameToParameter(Parameter * param, const std::vector<std::string> & val ) +{ + if( !this->CanCreateParameter<TParameterType>( param ) ) { - while( spaceSplitted[i][0] == ' ' ) - { - spaceSplitted[i] = spaceSplitted[i].substr(1, spaceSplitted[i].size()); - } + itkExceptionMacro("Impossible cast to add value to the parameter "<<param->GetKey()<<"."); } + + dynamic_cast<TParameterType *>(param)->SetFileNameList( val ); +} - for(unsigned int i=0; i<spaceSplitted.size(); i++) +template <class TParameterType> +void +CommandLineParser::SetFromFileNameToParameter(Parameter * param, const std::string & val ) +{ + if( !this->CanCreateParameter<TParameterType>( param ) ) { - std::cout<<spaceSplitted[i]<<std::endl; + itkExceptionMacro("Impossible cast to add value to the parameter "<<param->GetKey()<<"."); } + + dynamic_cast<TParameterType *>(param)->SetFromFileName( val ); +} +template <class TParameterType> +void +CommandLineParser::SetFromFileNameToParameter(Parameter * param, const std::vector<std::string> & val ) +{ + if( !this->CanCreateParameter<TParameterType>( param ) ) + { + itkExceptionMacro("Impossible cast to add value to the parameter "<<param->GetKey()<<"."); + } + + dynamic_cast<TParameterType *>(param)->SetListFromFileName( val ); +} - return spaceSplitted; +template <class TParameterType> +bool +CommandLineParser::CanCreateParameter( Parameter * param ) +{ + return dynamic_cast<TParameterType *>(param) != 0; } } diff --git a/Code/Wrappers/CommandLine/otbWrapperCommandLineParser.h b/Code/Wrappers/CommandLine/otbWrapperCommandLineParser.h index ca8805d539..e517f3fbd1 100644 --- a/Code/Wrappers/CommandLine/otbWrapperCommandLineParser.h +++ b/Code/Wrappers/CommandLine/otbWrapperCommandLineParser.h @@ -26,6 +26,7 @@ //#include "otbWrapperTypes.h" //#include "otbWrapperParameterGroup.h" #include "otbWrapperApplication.h" +#include "otbWrapperParameter.h" #include "itksys/SystemTools.hxx" namespace otb @@ -61,14 +62,14 @@ public: /** Parse result enum */ typedef enum { OK, EMPTYEXPRESSION, NOMODULENAME, MULTIPLEMODULENAME, INVALIDMODULENAME, WRONGMODULENAME, NOMODULEPATH, INVALIDMODULEPATH, - MISSINGMANDATORYATTRIBUT } ParseResultType; + MISSINGMANDATORYPARAMETER, MISSINGPARAMETERVALUE, WRONGPARAMETERVALUE, INVALIDNUMBEROFVALUE} ParseResultType; /** Check expression validity */ ParseResultType CheckExpression( const std::string & exp ); ParseResultType CheckExpression( const char * exp ); - bool CheckApplicationArgument( const std::string & exp ); - bool CheckApplicationArgument( const char * exp ); + CommandLineParser::ParseResultType ParseApplicationArgument( const std::string & exp ); + CommandLineParser::ParseResultType ParseApplicationArgument( const char * exp ); std::vector<itksys::String> GetAttribut( const std::string & key, const std::string & exp ); @@ -92,6 +93,27 @@ protected: std::string ExtractApplicationArgument( const char * exp ); + template <class TParameterType> + bool CanCreateParameter(Parameter * param); + + template <class TParameterType> + void SetValueToParameter(Parameter * param, const std::string & val ); + + template <class TParameterType> + void SetValueToParameter(Parameter * param, const std::vector<std::string> & val); + + template <class TParameterType> + void SetFileNameToParameter(Parameter * param, const std::string & val ); + + template <class TParameterType> + void SetFileNameToParameter(Parameter * param, const std::vector<std::string> & val); + + template <class TParameterType> + void SetFromFileNameToParameter(Parameter * param, const std::string & val ); + +template <class TParameterType> + void SetFromFileNameToParameter(Parameter * param, const std::vector<std::string> & val ); + private: CommandLineParser(const CommandLineParser &); //purposely not implemented diff --git a/Testing/CommandLine/otbWrapperCommandLineParserTests.cxx b/Testing/CommandLine/otbWrapperCommandLineParserTests.cxx index bc5e54753d..484401d4e4 100644 --- a/Testing/CommandLine/otbWrapperCommandLineParserTests.cxx +++ b/Testing/CommandLine/otbWrapperCommandLineParserTests.cxx @@ -36,16 +36,12 @@ int otbWrapperCommandLineParserTest(int argc, char* argv[]) ParserType::Pointer parser = ParserType::New(); - parser->GetAttribut("--lol", "sdfjnsf --plop johqsd qiudh --lol 65464 6315"); - parser->GetAttribut("--lol", "sdfjnsf --lol ===== **** -µµµµµ --plop johqsd qiudh "); - - ParserType::ParseResultType res = parser->CheckExpression( argv[1] ); - if( res == ParserType::OK) + /*if( res == ParserType::OK) { return EXIT_SUCCESS; } - else if( res == ParserType::EMPTYEXPRESSION ) + else */if( res == ParserType::EMPTYEXPRESSION ) { std::cout<<"Empty expression."<<std::endl; return EXIT_FAILURE; @@ -80,16 +76,27 @@ else if( res == ParserType::MULTIPLEMODULENAME ) std::cout<<"No module path specified."<<std::endl; return EXIT_FAILURE; } -else if( res == ParserType::MISSINGMANDATORYATTRIBUT ) + + + ParserType::ParseResultType res2 = parser->ParseApplicationArgument( argv[1] ); + + if( res2 == ParserType::MISSINGMANDATORYPARAMETER ) { - std::cout<<"Missing mandatory attribut."<<std::endl; + std::cout<<"Missing mandatory parameter."<<std::endl; return EXIT_FAILURE; } - else + else if( res2 == ParserType::MISSINGPARAMETERVALUE ) { - std::cout<<"Unknown internal error."<<std::endl; + std::cout<<"Missing parameter value."<<std::endl; return EXIT_FAILURE; } + else if( res2 == ParserType::INVALIDNUMBEROFVALUE ) + { + std::cout<<"Invalid number of parameter values."<<std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; } -- GitLab