An error occurred while loading the file. Please try again.
-
Guillaume Perréal authoreda73e273c
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "otbWrapperCommandLineLauncher.h"
// Single value parameter
#include "otbWrapperChoiceParameter.h"
#include "otbWrapperDirectoryParameter.h"
#include "otbWrapperInputFilenameParameter.h"
#include "otbWrapperOutputFilenameParameter.h"
#include "otbWrapperInputImageParameter.h"
#include "otbWrapperInputVectorDataParameter.h"
#include "otbWrapperOutputImageParameter.h"
#include "otbWrapperOutputVectorDataParameter.h"
#include "otbWrapperNumericalParameter.h"
#include "otbWrapperListViewParameter.h"
#include "otbWrapperOutputProcessXMLParameter.h"
#include "otbWrapperAddProcessToWatchEvent.h"
// List value parameter
#include "otbWrapperInputImageListParameter.h"
#include "otbWrapperInputVectorDataListParameter.h"
#include "otbWrapperInputFilenameListParameter.h"
#include "otbWrapperStringListParameter.h"
#include "otbWrapperApplicationRegistry.h"
#include "otbWrapperTypes.h"
#include <itksys/RegularExpression.hxx>
#include <string>
#include <iostream>
using std::string;
namespace otb
{
namespace Wrapper
{
CommandLineLauncher::CommandLineLauncher() :
/*m_Expression(""),*/m_VExpression(), m_WatcherList(), m_ReportProgress(true)
{
m_Application = nullptr;
m_Parser = CommandLineParser::New();
m_LogOutput = itk::StdStreamLogOutput::New();
m_LogOutput->SetStream(std::cout);
// Add the callback to be added when a AddProcessToWatch event is invoked
m_AddProcessCommand = AddProcessCommandType::New();
m_AddProcessCommand->SetCallbackFunction(this, &CommandLineLauncher::LinkWatchers);
}
CommandLineLauncher::~CommandLineLauncher()
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
{
this->DeleteWatcherList();
m_Application = nullptr;
ApplicationRegistry::CleanRegistry();
}
void CommandLineLauncher::DeleteWatcherList()
{
for (unsigned int i = 0; i < m_WatcherList.size(); i++)
{
delete m_WatcherList[i];
m_WatcherList[i] = nullptr;
}
m_WatcherList.clear();
}
bool CommandLineLauncher::Load(const std::vector<std::string> &vexp)
{
m_VExpression = vexp;
return this->Load();
}
bool CommandLineLauncher::Load()
{
if (this->CheckParametersPrefix() == false)
{
std::cerr << "ERROR: Parameters are set using \"-\", not \"--\"." << std::endl;
return false;
}
if (this->CheckUnicity() == false)
{
std::cerr << "ERROR: At least one parameter is not unique in the expression." << std::endl;
return false;
}
if (this->LoadPath() == false)
{
if (m_Parser->GetPathsAsString(m_VExpression).size() != 0)
{
std::cerr << "ERROR: At least one specified path within \"" << m_Parser->GetPathsAsString(m_VExpression)
<< "\" is invalid or doesn't exist." << std::endl;
return false;
}
}
return this->LoadApplication();
}
bool CommandLineLauncher::Execute()
{
if (this->BeforeExecute() == false)
{
return false;
}
if( m_Application->Execute() == 0 )
{
this->DisplayOutputParameters();
return true;
}
else
return false;
}
bool CommandLineLauncher::ExecuteAndWriteOutputNoCatch()
{
if (this->BeforeExecute() == false)
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
{
return false;
}
if( m_Application->ExecuteAndWriteOutput() == 0 )
{
this->DisplayOutputParameters();
}
else
{
return false;
}
return true;
}
bool CommandLineLauncher::ExecuteAndWriteOutput()
{
// If testenv is used, do not catch exceptions
if (m_Parser->IsAttributExists("-testenv", m_VExpression) == true)
{
return ExecuteAndWriteOutputNoCatch();
}
else
{
try
{
return ExecuteAndWriteOutputNoCatch();
}
catch(otb::ApplicationException& err)
{
// These are thrown with otbAppLogFATAL, a macro which logs a user
// friendly error message before throwing. So log exception details only
// in debug.
m_Application->GetLogger()->Debug("Caught otb::ApplicationException during application execution:\n");
m_Application->GetLogger()->Debug(string(err.what()) + "\n");
return false;
}
catch(otb::ImageFileReaderException& err)
{
m_Application->GetLogger()->Debug("Caught otb::ImageFileReaderException during application execution:\n");
m_Application->GetLogger()->Debug(string(err.what()) + "\n");
m_Application->GetLogger()->Fatal(err.GetDescription() + string("\n"));
return false;
}
catch(itk::ExceptionObject& err)
{
m_Application->GetLogger()->Debug("Caught itk::ExceptionObject during application execution:\n");
m_Application->GetLogger()->Debug(string(err.what()) + "\n");
m_Application->GetLogger()->Fatal(string(err.GetDescription()) + "\n");
return false;
}
catch(std::exception& err)
{
m_Application->GetLogger()->Fatal(std::string("Caught std::exception during application execution: ") + err.what() + "\n");
return false;
}
catch(...)
{
m_Application->GetLogger()->Fatal("Caught unknown exception during application execution.\n");
return false;
}
}
}
bool CommandLineLauncher::BeforeExecute()
{
if (m_Application.IsNull())
{
std::cerr << "ERROR: No loaded application." << std::endl;
return false;
}
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
// Check if there's keys in the expression if the application takes
// at least 1 mandatory parameter
const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
std::vector<std::string> keyList = m_Parser->GetKeyList( m_VExpression );
if( appKeyList.size()!=0 && keyList.size()==0 )
{
std::cerr << "ERROR: Waiting for at least one parameter." << std::endl;
std::cerr << std::endl;
this->DisplayHelp();
return false;
}
// if help is asked...
if (m_Parser->IsAttributExists("-help", m_VExpression) == true)
{
std::vector<std::string> val;
val = m_Parser->GetAttribut("-help", m_VExpression);
if(val.empty())
{
this->DisplayHelp(true);
}
else
{
for(std::vector<std::string>::const_iterator it = val.begin(); it!=val.end();++it)
{
Parameter::Pointer param = m_Application->GetParameterByKey(*it);
if (param->GetRole() != Role_Output)
{
std::cerr << this->DisplayParameterHelp(param, *it,true)<<std::endl;
}
}
}
return false;
}
//display OTB version
if (m_Parser->IsAttributExists("-version", m_VExpression) == true)
{
std::cerr << "This is the "<<m_Application->GetName() << " application, version " << OTB_VERSION_STRING <<std::endl;
return false;
}
// if we want to load test environnement
if (m_Parser->IsAttributExists("-testenv", m_VExpression) == true)
{
this->LoadTestEnv();
}
// Check the key validity (ie. exist in the application parameters)
std::string unknownKey;
if (this->CheckKeyValidity(unknownKey) == false)
{
std::cerr << "ERROR: Parameter -" << unknownKey <<" does not exist in the application." << std::endl;
return false;
}
ParamResultType result = this->LoadParameters();
if (result == MISSINGMANDATORYPARAMETER)
{
std::cerr << std::endl;
this->DisplayHelp();
return false;
}
else if (result != OKPARAM)
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
{
return false;
}
if (m_Application->IsDeprecated())
{
m_Application->GetLogger()->Warning("This application is deprecated and will be removed in a future OTB release.\n");
}
return true;
}
bool CommandLineLauncher::LoadPath()
{
std::vector<std::string> pathList;
// If users has set path...
//if (m_Parser->GetPaths(pathList, m_Expression) == CommandLineParser::OK)
if (m_Parser->GetPaths(pathList, m_VExpression) == CommandLineParser::OK)
{
for (unsigned i = 0; i < pathList.size(); i++)
{
ApplicationRegistry::AddApplicationPath(pathList[i]);
}
}
else
{
return false;
}
return true;
}
bool CommandLineLauncher::LoadApplication()
{
// Look for the module name
std::string moduleName;
if (m_Parser->GetModuleName(moduleName, m_VExpression) != CommandLineParser::OK)
{
std::cerr << "ERROR: Invalid module name: " << m_VExpression[0] << "." << std::endl;
return false;
}
// Instantiate the application using the factory
m_Application = ApplicationRegistry::CreateApplication(moduleName);
if (m_Application.IsNull())
{
std::cerr << "ERROR: Could not find application \"" << moduleName << "\"" << std::endl;
std::string modulePath = ApplicationRegistry::GetApplicationPath();
std::cerr << "ERROR: Module search path: " << (modulePath.empty() ? "none (check OTB_APPLICATION_PATH)" : modulePath) << std::endl;
std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
if (list.size() == 0)
{
std::cerr << "ERROR: Available modules: none." << std::endl;
}
else
{
std::cerr << "ERROR: Available modules:" << std::endl;
for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
{
std::cerr << "\t" << *it << std::endl;
}
}
return false;
}
else
{
// Attach log output to the Application logger
m_Application->GetLogger()->AddLogOutput(m_LogOutput);
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
// Add an observer to the AddedProcess event
m_Application->AddObserver(AddProcessToWatchEvent(), m_AddProcessCommand.GetPointer());
return true;
}
}
CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters()
{
if (m_Application.IsNull())
{
itkExceptionMacro("No application loaded");
}
/* Check for inxml parameter. If exists Update all Parameters from xml and
* check for user defined parameters for overriding those from XML
*/
const char *inXMLKey = "inxml";
const char *attrib = "-inxml";
const bool paramInXMLExists(m_Parser->IsAttributExists(attrib, m_VExpression));
if(paramInXMLExists)
{
std::vector<std::string> inXMLValues;
inXMLValues = m_Parser->GetAttribut(attrib, m_VExpression);
m_Application->SetParameterString(inXMLKey, inXMLValues[0]);
m_Application->UpdateParameters();
}
// Check for the progress report parameter
if (m_Parser->IsAttributExists("-progress", m_VExpression) == true)
{
std::vector<std::string> val = m_Parser->GetAttribut("-progress", m_VExpression);
if (val.size() == 1 && (val[0] == "1" || val[0] == "true"))
{
m_ReportProgress = true;
}
else if (val.size() == 1 && (val[0] == "0" || val[0] == "false"))
{
m_ReportProgress = false;
}
else
{
std::cerr << "ERROR: Invalid value for parameter -progress. It must be 0, 1, false or true." << std::endl;
return WRONGPARAMETERVALUE;
}
}
const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
// Loop over each parameter key declared in the application
// FIRST PASS : set parameter values
for (unsigned int i = 0; i < appKeyList.size(); i++)
{
const std::string paramKey(appKeyList[i]);
std::vector<std::string> values;
ParameterType type = m_Application->GetParameterType(paramKey);
const bool paramExists(m_Parser->IsAttributExists(std::string("-").append(paramKey), m_VExpression));
// if param is a Group, don't do anything, ParamGroup don't have values
if (type != ParameterType_Group)
{
// Get the attribute relative to this key as vector
values = m_Parser->GetAttribut(std::string("-").append(paramKey), m_VExpression);
// If the param does not exists in the cli, don't try to set a
// value on it, an exception will be thrown later in this function
if (paramExists)
{
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
// Check if there is a value associated to the attribute
if ( values.empty() )
{
std::cerr << "ERROR: No value associated to parameter -" << paramKey << "." << std::endl;
return INVALIDNUMBEROFVALUE;
}
if (type == ParameterType_InputVectorDataList ||
type == ParameterType_InputImageList ||
type == ParameterType_InputFilenameList ||
type == ParameterType_StringList ||
type == ParameterType_ListView)
{
// Multiple values parameters
m_Application->SetParameterStringList(paramKey, values);
}
else if (type == ParameterType_Choice ||
type == ParameterType_Float ||
type == ParameterType_Int ||
type == ParameterType_Radius ||
type == ParameterType_Directory ||
type == ParameterType_String ||
type == ParameterType_InputFilename ||
type == ParameterType_OutputFilename ||
type == ParameterType_InputImage ||
type == ParameterType_OutputImage ||
type == ParameterType_InputVectorData ||
type == ParameterType_OutputVectorData ||
type == ParameterType_RAM ||
type == ParameterType_OutputProcessXML ||
type == ParameterType_Bool) // || type == ParameterType_InputProcessXML)
{
// Single value parameter
m_Application->SetParameterString(paramKey, values[0]);
if (type == ParameterType_OutputImage)
{
// Check if pixel type is given
if (values.size() == 2)
{
ImagePixelType pixType = ImagePixelType_float;
if ( !OutputImageParameter::ConvertStringToPixelType(values[1],pixType) )
{
std::cerr << "ERROR: Invalid output type for parameter -" <<
paramKey << ": " << values[1] << "." << std::endl;
return WRONGPARAMETERVALUE;
}
m_Application->SetParameterOutputImagePixelType(paramKey, pixType);
}
else if (values.size() > 2)
{
std::cerr << "ERROR: Too many values for parameter -" <<
paramKey << " (expected 2 or 1, got " << values.size() << ")."
<< std::endl;
return INVALIDNUMBEROFVALUE;
}
}
}
// Call the DoUpdateParameter to update dependent params
m_Application->UpdateParameters();
}
}
}
// SECOND PASS : checks
for (const auto & paramKey : appKeyList)
{
// Check for missing mandatory parameters
if(!CheckMissingMandatoryParameter(paramKey))
return MISSINGMANDATORYPARAMETER;
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
// Check and warn unused parameters
CheckUnusedParameter(paramKey);
// Check output paths are valid
if(!CheckOutputPathsValidity(paramKey))
return WRONGPARAMETERVALUE;
}
return OKPARAM;
}
bool CommandLineLauncher::CheckOutputPathsValidity(const std::string & paramKey) const
{
ParameterType type = m_Application->GetParameterType(paramKey);
if (m_Application->HasValue(paramKey) &&
type == ParameterType_OutputFilename)
{
std::string filename = m_Application->GetParameterString(paramKey);
itksys::String path = itksys::SystemTools::GetFilenamePath(filename);
if (path!="" && !itksys::SystemTools::FileIsDirectory(path))
{
std::cerr <<"ERROR: Directory doesn't exist : "<< path << std::endl;
return false;
}
}
return true;
}
bool CommandLineLauncher::CheckMissingMandatoryParameter(const std::string & paramKey) const
{
if (m_Application->IsParameterMissing(paramKey))
{
std::cerr << "ERROR: Missing mandatory parameter -" << paramKey << "." << std::endl;
return false;
}
return true;
}
void CommandLineLauncher::CheckUnusedParameter(const std::string & paramKey) const
{
// Check for ignored parameters
if(m_Application->HasUserValue(paramKey))
{
// Find the position of the next dot
unsigned int start = 0;
auto end = paramKey.find_first_of('.',start);
// Until we reach en of key
while(end != std::string::npos)
{
// Extract key until the current dot
const std::string & key = paramKey.substr(0,end);
// Find the corresponding parameter type
ParameterType type = m_Application->GetParameterType(key);
// In any case update the position of current and next dot
start = end+1;
end = paramKey.find_first_of('.',start);
// If the current parameter (paramKey) has a choice in it
if(type == ParameterType_Choice)
{
const std::string & value = m_Application->GetParameterString(key);
// Check that this choice is active
if(paramKey.find(value) == std::string::npos)
{
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
std::cerr<<"WARNING: Parameter -"<<paramKey<<" will be ignored because -"<<key<<" is "<<value<<"."<<std::endl;
break;
}
}
}
}
}
void CommandLineLauncher::LinkWatchers(itk::Object * itkNotUsed(caller), const itk::EventObject & event)
{
// Report the progress only if asked
if (m_ReportProgress)
{
if (typeid(otb::Wrapper::AddProcessToWatchEvent) == typeid( event ))
{
const AddProcessToWatchEvent* eventToWatch = dynamic_cast<const AddProcessToWatchEvent*> (&event);
auto watch = new StandardOneLineFilterWatcher<>(eventToWatch->GetProcess(),
eventToWatch->GetProcessDescription());
m_WatcherList.push_back(watch);
}
}
}
void CommandLineLauncher::DisplayHelp(bool longHelp)
{
std::cerr<<std::endl;
std::cerr << "This is the "<<m_Application->GetDocName() << " ("<<m_Application->GetName()<<") application, version " << OTB_VERSION_STRING <<std::endl<<std::endl;
if (m_Application->IsDeprecated())
{
std::cerr << "WARNING: This application is deprecated, it will be removed in a future OTB release." << std::endl;
std::cerr << std::endl;
}
std::cerr << m_Application->GetDescription() << std::endl;
if(longHelp)
{
std::cerr<<"Tags: ";
std::vector<std::string> tags = m_Application->GetDocTags();
for(std::vector<std::string>::const_iterator it = tags.begin(); it!=tags.end();++it)
{
std::cerr<<*it<<" ";
}
std::cerr<<std::endl;
std::cerr<<std::endl;
std::cerr<<m_Application->GetDocLongDescription() << std::endl;
std::cerr<<std::endl;
}
else
{
std::string link = m_Application->GetDocLink();
if (!link.empty())
{
std::cerr << "Complete documentation: " << link << " or -help" <<std::endl;
std::cerr<<std::endl;
}
}
std::cerr << "Parameters: " << std::endl;
const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
const unsigned int nbOfParam = appKeyList.size();
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
unsigned int maxKeySize = GetMaxKeySize();
//// progress report parameter
std::string bigKey = "progress";
for(unsigned int i=0; i<maxKeySize-std::string("progress").size(); i++)
bigKey.append(" ");
for (unsigned int i = 0; i < nbOfParam; i++)
{
Parameter::Pointer param = m_Application->GetParameterByKey(appKeyList[i]);
if (param->GetRole() != Role_Output)
{
std::cerr << this->DisplayParameterHelp(param, appKeyList[i]);
}
}
std::cerr << " -"<<bigKey<<" <boolean> Report progress " << std::endl;
bigKey = "help";
for(unsigned int i=0; i<maxKeySize-std::string("help").size(); i++)
bigKey.append(" ");
std::cerr << " -"<<bigKey<<" <string list> Display long help (empty list), or help for given parameters keys" << std::endl;
std::cerr<<std::endl;
//std::string cl(m_Application->GetCLExample());
std::cerr<<"Use -help param1 [... paramN] to see detailed documentation of those parameters."<<std::endl;
std::cerr<<std::endl;
std::cerr << "Examples: " << std::endl;
std::cerr << m_Application->GetCLExample() << std::endl;
if(longHelp)
{
std::cerr<<"Authors: "<<std::endl<<m_Application->GetDocAuthors() << std::endl;
std::cerr<<std::endl;
std::cerr<<"Limitations: "<<std::endl<<m_Application->GetDocLimitations() << std::endl;
std::cerr<<std::endl;
std::cerr<<"See also: "<<std::endl<<m_Application->GetDocSeeAlso() << std::endl;
std::cerr<<std::endl;
}
}
void CommandLineLauncher::LoadTestEnv()
{
//Set seed for rand and itk mersenne twister
//srand(1);
// itk::Statistics::MersenneTwisterRandomVariateGenerator::GetInstance()->SetSeed(121212);
}
std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer & param, const std::string paramKey, bool longHelp)
{
// Display the type the type
ParameterType type = m_Application->GetParameterType(paramKey);
std::string bigKey = paramKey;
unsigned int maxKeySize = GetMaxKeySize();
bool singleSelectionForListView = false;
if(type == ParameterType_ListView)
{
ListViewParameter * tmp = static_cast<ListViewParameter *>(param.GetPointer());
singleSelectionForListView = tmp->GetSingleSelection();
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
}
std::ostringstream oss;
if( m_Application->IsParameterMissing(paramKey) )
{
oss << "MISSING ";
}
else
{
oss << " ";
}
for(unsigned int i=0; i<maxKeySize-paramKey.size(); i++)
bigKey.append(" ");
oss<< "-" << bigKey << " ";
// Display the type the parameter
if (type == ParameterType_Radius || type == ParameterType_Int || type == ParameterType_RAM)
{
oss << "<int32> ";
}
else if (type == ParameterType_Bool)
{
oss << "<boolean> ";
}
else if (type == ParameterType_Float)
{
oss << "<float> ";
}
else if (type == ParameterType_InputFilename || type == ParameterType_OutputFilename ||type == ParameterType_Directory || type == ParameterType_InputImage || type == ParameterType_OutputProcessXML || type == ParameterType_InputProcessXML ||
type == ParameterType_InputVectorData || type == ParameterType_OutputVectorData || type == ParameterType_String ||
type == ParameterType_Choice || (type == ParameterType_ListView && singleSelectionForListView))
{
oss << "<string> ";
}
else if (type == ParameterType_OutputImage)
{
oss << "<string> [pixel]";
}
else if (type == ParameterType_Choice || (type == ParameterType_ListView && !singleSelectionForListView) || type == ParameterType_InputImageList ||
type == ParameterType_InputVectorDataList || type == ParameterType_InputFilenameList ||
type == ParameterType_StringList )
{
oss << "<string list> ";
}
else if(type == ParameterType_Group)
{
oss<< "<group> ";
}
else
itkExceptionMacro("Not handled parameter type.");
oss<< " " << m_Application->GetParameterName(paramKey) << " ";
if (type == ParameterType_OutputImage)
{
OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param.GetPointer());
std::string defPixType("float");
if (paramDown)
{
defPixType = OutputImageParameter::ConvertPixelTypeToString(paramDown->GetDefaultPixelType());
}
oss << " [pixel=uint8/uint16/int16/uint32/int32/float/double/cint16/cint32/cfloat/cdouble]";
oss << " (default value is " << defPixType <<")";
}
if (type == ParameterType_Choice)
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
{
ChoiceParameter* paramDown = dynamic_cast<ChoiceParameter*>(param.GetPointer());
if (paramDown)
{
std::vector<std::string> keys = paramDown->GetChoiceKeys();
std::vector<std::string> names = paramDown->GetChoiceNames();
oss << "[";
for(unsigned int i=0; i<keys.size(); i++)
{
oss<<keys[i];
if( i != keys.size()-1 )
oss << "/";
}
oss << "]";
}
}
if(type != ParameterType_Group)
{
if(m_Application->IsMandatory(paramKey))
{
oss<<" (mandatory";
}
else
{
oss<<" (optional";
if(m_Application->IsParameterEnabled(paramKey))
{
oss<<", on by default";
}
else
{
oss<<", off by default";
}
}
if(m_Application->HasValue(paramKey))
{
if ( m_Application->GetParameterAsString(paramKey).empty() )
oss<<", no default value";
else
{
oss<<", default value is "
<<m_Application->GetParameterAsString(paramKey);
}
}
oss<<")";
}
oss << std::endl;
if(longHelp)
{
oss << " ";
for(unsigned int i=0; i<maxKeySize;++i)
oss<<" ";
oss<<" ";
oss<<m_Application->GetParameterDescription(paramKey)<<std::endl;
if (type == ParameterType_Choice)
{
std::vector<std::string> keys = dynamic_cast<ChoiceParameter*>(param.GetPointer())->GetChoiceKeys();
std::vector<std::string> names = dynamic_cast<ChoiceParameter*>(param.GetPointer())->GetChoiceNames();
auto keyIt = keys.begin();
auto nameIt = names.begin();
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
for( ; keyIt!=keys.end()&&nameIt!=names.end();++keyIt,++nameIt)
{
oss << " ";
for(unsigned int i=0; i<maxKeySize;++i)
oss<<" ";
oss<<" ";
oss<<"- "<<*nameIt<<" ("<<*keyIt<<"): "<<m_Application->GetParameterDescription(paramKey+"."+(*keyIt))<<std::endl;
}
}
}
return oss.str();
}
bool CommandLineLauncher::CheckUnicity()
{
bool res = true;
// Extract expression keys
//std::vector<std::string> keyList = m_Parser->GetKeyList(m_Expression);
std::vector<std::string> keyList = m_Parser->GetKeyList(m_VExpression);
// Check Unicity
for (unsigned int i = 0; i < keyList.size(); i++)
{
std::vector<std::string> listTmp = keyList;
const std::string keyRef = keyList[i];
listTmp.erase(listTmp.begin() + i);
for (unsigned int j = 0; j < listTmp.size(); j++)
{
if (keyRef == listTmp[j])
{
res = false;
break;
}
}
if (!res)
break;
}
return res;
}
bool CommandLineLauncher::CheckParametersPrefix()
{
// Check if the chain " --" appears in the args, could be a common mistake
for (std::vector<std::string>::iterator it = m_VExpression.begin(); it != m_VExpression.end(); ++it)
{
if (it->compare(0, 2, "--") == 0 )
{
return false;
}
}
return true;
}
bool CommandLineLauncher::CheckKeyValidity(std::string& refKey)
{
bool res = true;
// Extract expression keys
std::vector<std::string> expKeyList = m_Parser->GetKeyList(m_VExpression);
// Extract application keys
std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
appKeyList.push_back("help");
appKeyList.push_back("progress");
appKeyList.push_back("testenv");
appKeyList.push_back("version");
// Check if each key in the expression exists in the application
for (unsigned int i = 0; i < expKeyList.size(); i++)
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
{
refKey = expKeyList[i];
bool keyExist = false;
for (unsigned int j = 0; j < appKeyList.size(); j++)
{
if (refKey == appKeyList[j])
{
keyExist = true;
break;
}
}
if (keyExist == false)
{
res = false;
break;
}
}
return res;
}
void CommandLineLauncher::DisplayOutputParameters()
{
std::vector< std::pair<std::string, std::string> > paramList;
paramList = m_Application->GetOutputParametersSumUp();
if( paramList.size() == 0 )
return;
std::ostringstream oss;
for( unsigned int i=0; i<paramList.size(); i++)
{
oss << paramList[i].first;
oss << ": ";
oss << paramList[i].second;
oss << std::endl;
}
if ( m_Parser->IsAttributExists("-testenv", m_VExpression) )
{
std::vector<std::string> val = m_Parser->GetAttribut("-testenv", m_VExpression);
if( val.size() == 1 )
{
std::ofstream ofs(val[0]);
if (!ofs.is_open())
{
fprintf(stderr, "Error, can't open file");
itkExceptionMacro( << "Error, can't open file "<<val[0]<<".");
}
ofs << oss.str();
ofs.close();
}
}
std::cout << "Output parameters value:" << std::endl;
std::cout << oss.str() << std::endl;
}
unsigned int CommandLineLauncher::GetMaxKeySize() const
{
const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
const unsigned int nbOfParam = appKeyList.size();
unsigned int maxKeySize = std::string("progress").size();
for (unsigned int i = 0; i < nbOfParam; i++)
{
if (m_Application->GetParameterRole(appKeyList[i]) != Role_Output)
{
if( maxKeySize < appKeyList[i].size() )
981982983984985986987988989990
maxKeySize = appKeyList[i].size();
}
}
return maxKeySize;
}
}
}