From b2c1f27f9004c4a722aa4219e16f0aa546b1994f Mon Sep 17 00:00:00 2001
From: Thomas Feuvrier <thomas.feuvrier@c-s.fr>
Date: Mon, 20 Feb 2006 13:05:05 +0000
Subject: [PATCH] nomsg

---
 Code/Common/otbCommandLineArgumentParser.cxx  | 331 +++++++++++++-----
 Code/Common/otbCommandLineArgumentParser.h    |  66 ++--
 Code/Common/otbCommandLineArgumentParser.txx  |  56 +--
 .../otbTestCommandLineArgumentParser.cxx      |  39 ++-
 4 files changed, 330 insertions(+), 162 deletions(-)

diff --git a/Code/Common/otbCommandLineArgumentParser.cxx b/Code/Common/otbCommandLineArgumentParser.cxx
index b59d7343cd..3d7ce50de5 100755
--- a/Code/Common/otbCommandLineArgumentParser.cxx
+++ b/Code/Common/otbCommandLineArgumentParser.cxx
@@ -6,40 +6,138 @@
 namespace otb
 {
 
+
+// --------- CommandLineArgumentParseResult  ----------------------------------------
+void
+CommandLineArgumentParseResult
+::PrintSelf(std::ostream& os/*, itk::Indent indent*/)const
+{
+
+
+}
+
+
+
+
+bool 
+CommandLineArgumentParseResult
+::IsOptionPresent(const char *option)const
+{
+  return (m_OptionMap.find(std::string(option)) != m_OptionMap.end());
+}
+
+
+
+
+std::string 
+CommandLineArgumentParseResult
+::GetStringParameter(const char *option, unsigned int number)const
+{
+  assert(this->IsOptionPresent(option));
+  
+  OptionMapType::const_iterator it = m_OptionMap.begin();
+  it = m_OptionMap.find(std::string(option));
+  
+//  assert(number < m_OptionMap[std::string(option)].size());
+ParameterArrayType pat = (*it).second;
+
+std::string lString = pat[number];
+
+  return ( lString );
+}
+int  
+CommandLineArgumentParseResult
+::GetNumberOfParameters(const char *option)
+{
+  assert(IsOptionPresent(option));
+  return (m_OptionMap[std::string(option)].size());
+}
+
+
+
+
+void  
+CommandLineArgumentParseResult
+::Clear()
+{
+  m_OptionMap.clear();
+}
+
+void  
+CommandLineArgumentParseResult
+::AddOption(const std::string &option)
+{
+  ParameterArrayType pat;
+//  pat.reserve(nParms);
+  m_OptionMap[option] = pat;
+}
+
+void  
+CommandLineArgumentParseResult
+::AddParameter(const std::string &option, const std::string &parameter)
+{
+  m_OptionMap[option].push_back(parameter);  
+}
+
+
+// --------- CommandLineArgumentParser  ----------------------------------------
 void 
 CommandLineArgumentParser
-::AddOption(const char *name, const int nParameters, const char * comment)
+::AddOption(const char *name, const  char * comment, char *synonim, int nParameters, bool obligatory )
 {
   // Create a structure for the command
   OptionType option;
-  option.CommonName = std::string(name);
-  option.CommentName = std::string(comment);
+  option.CommonName  = std::string(name);
+  option.Description = std::string(comment);
+  option.Synonim     = std::string(synonim);
   option.NumberOfParameters = nParameters;
+  option.NumberOfParametersFixed = true;
+  option.Obligatory = obligatory;
+  option.Finded = false;
 
   // Add the option to the map
-  m_OptionMap[std::string(name)] = option;
+  m_OptionList.push_back(option);
+  
 }
 
 void 
 CommandLineArgumentParser
-::AddSynonim(const char *option, const char *synonim)
+::AddOptionNParams(const char *name, const char * comment, char *synonim, bool obligatory )
 {
-  std::string strOption(option);
-  std::string strSynonim(synonim);
+  // Create a structure for the command
+  OptionType option;
+  option.CommonName  = std::string(name);
+  option.Description = std::string(comment);
+  option.Synonim     = std::string(synonim);
+  option.NumberOfParameters = -1;
+  option.NumberOfParametersFixed = false;
+  option.Obligatory = obligatory;
+  option.Finded = false;
 
-  // The option should exist!
-  assert(m_OptionMap.find(strOption) != m_OptionMap.end());
+  // Add the option to the map
+  m_OptionList.push_back(option);
 
-  // Create a new option object
-  OptionType o;
-  o.NumberOfParameters = m_OptionMap[strOption].NumberOfParameters;
-  o.CommentName = m_OptionMap[strOption].CommentName;
-  o.CommonName = strOption;
+	
+}
 
-  // Insert the option into the map
-  m_OptionMap[strSynonim] = o;
+void 
+CommandLineArgumentParser
+::ParseCommandLine(int argc, char *argv[], 
+                           CommandLineArgumentParseResult &outResult,
+                           bool failOnUnknownTrailingParameters )
+{
+	
+	bool tryParse = TryParseCommandLine(argc, argv, outResult, failOnUnknownTrailingParameters);
+	if ( tryParse == false )
+	{
+		PrintUsage(std::cerr);
+		//Exit du programme (cette méthode doit etre appelée dans un main)
+		// ou itkException ???
+		exit(EXIT_FAILURE);
+	}
 }
 
+
 bool 
 CommandLineArgumentParser
 ::TryParseCommandLine(int argc, char *argv[], 
@@ -50,7 +148,8 @@ CommandLineArgumentParser
   outResult.Clear();
 
   m_ProgramName = std::string(argv[0]);
-
+  int index(0);
+  
   // Go through the arguments
   for(int i=1; i < argc; i++)
     {
@@ -58,112 +157,150 @@ CommandLineArgumentParser
     std::string arg(argv[i]);
 
     // Check if the argument is known
-    if(m_OptionMap.find(arg) == m_OptionMap.end())
+    bool findOption = FindOption( arg, index );
+      if (findOption == false)
       {
       if(failOnUnknownTrailingParameters)
         {
         // Unknown argument found
-        std::cerr << "Unrecognized command line option '" << arg << "'" << std::endl;
+        std::cerr << "Option '" << arg << "' non reconnue !!!" << std::endl;
         return false;
         }
       else return true;
       }
+    //Check the option
+    m_OptionList[index].Finded = true;
+    // Si le nombre de parametres est prédéfini : 
+    if (m_OptionList[index].NumberOfParametersFixed == true)
+    {
+    	// Check if the number of parameters is correct
+    	int nParameters = m_OptionList[index].NumberOfParameters;
+    	if(i+nParameters >= argc) 
+      	{
+      		// Too few parameters
+      		std::cerr << "Il manque un (ou plusieurs) parametre(s) pour l'option '" << arg << "'" << std::endl;
+      		return false;
+      	}
+        // Tell the result that the option has been encountered
+        outResult.AddOption(m_OptionList[index].CommonName);
+
+        // Pass in the parameters
+        for(int j=0;j<nParameters;j++,i++)
+        {
+      		outResult.AddParameter(m_OptionList[index].CommonName,std::string(argv[i+1]));
+      	}
+     }
+     // Si le nombre de parametres n'est pas prédéfini, lecture jusqu'a la prochaine option ou fin argv  : 
+     else
+     {
+         // Tell the result that the option has been encountered
+        outResult.AddOption(m_OptionList[index].CommonName);
+    	bool continuer(true);
+     	while (continuer == true )
+     	{
+     		if ( argv[i+1] != NULL )
+     		{
+     			std::string strArgv = std::string(argv[i+1]);
+     			if ( strArgv[0] == '-' )
+     			{
+     				continuer = false;
+     			}
+     			else
+     			{
+      				outResult.AddParameter(m_OptionList[index].CommonName,strArgv);
+     			}
+     		}
+     		else continuer = false;
+     		i++;
+     	}
+     }
 
-    // Check if the number of parameters is correct
-    int nParameters = m_OptionMap[arg].NumberOfParameters;
-    if(i+nParameters >= argc) 
-      {
-      // Too few parameters
-      std::cerr << "Too few parameters to command line option '" << arg << "'" << std::endl;
-      return false;
-      }
-
-    // Tell the result that the option has been encountered
-    outResult.AddOption(m_OptionMap[arg].CommonName,nParameters);
-
-    // Pass in the parameters
-    for(int j=0;j<nParameters;j++,i++)
-      outResult.AddParameter(m_OptionMap[arg].CommonName,std::string(argv[i+1]));
+    
+    
     
     }
 
+  // Controle que toutes les options obligatoire sont présentes dans la ligne d'argument
+  for(int i=0 ; i < m_OptionList.size() ; i++ )
+  {
+  	if ( (m_OptionList[i].Obligatory == true) && (m_OptionList[i].Finded == false) )
+  	{
+      		// Too few parameters
+      		std::cerr << "L'option '" << m_OptionList[i].CommonName << "' est obligatoire !!!" << std::endl;
+      		return false;
+	}	
+  }
+  
   // Everything is good
   return true;
 }
 
-void
+bool 
 CommandLineArgumentParser
-::PrintUsage(std::ostream& os/*, itk::Indent indent*/)const
+::FindOption(const std::string & option, int & index)
 {
-        os << " Usage : "<<m_ProgramName<<std::endl;
-        OptionMapType::const_iterator iterMap = m_OptionMap.begin();
-        
-//        iterMap.first
-/*        while ( ! iterMap.end() )
-        {
-                os << iterMap<<std::endl;
-                ++iterMap;
-        }*/
-
+	//Cherche dans la liste des options installées
+	bool trouve(false);
+	bool continuer(true);
+	int cpt(0);
+	std::string strOption(option);
+	while ( continuer == true )
+	{
+		if (  (m_OptionList[cpt].CommonName == strOption) || (m_OptionList[cpt].Synonim == strOption) )
+		{
+			index = cpt;
+			continuer = false;
+			trouve = true;	
+		}
+		cpt++;
+		if( cpt >= m_OptionList.size() )
+		{
+			continuer = false;	
+		}
+	}
+        return (trouve);
 }
 
-
-// --------- CommandLineArgumentParseResult  ----------------------------------------
 void
-CommandLineArgumentParseResult
-::PrintSelf(std::ostream& os/*, itk::Indent indent*/)const
-{
-
-
-}
-
-
-
-
-
-
-
-
-bool 
-CommandLineArgumentParseResult
-::IsOptionPresent(const char *option)
+CommandLineArgumentParser
+::PrintUsage(std::ostream& os/*, itk::Indent indent*/)const
 {
-  return (m_OptionMap.find(std::string(option)) != m_OptionMap.end());
+	os << std::endl;
+        os << " Usage : "<<m_ProgramName<<std::endl;
+  	// Calcul de la largeur max en caractere de l'affichage des options (pour mise en page)
+  	int largeurmax(-1);
+  	for(int i=0 ; i < m_OptionList.size() ; i++ )
+  	{
+  		int largeur = m_OptionList[i].CommonName.size() + m_OptionList[i].Synonim.size();
+  		if ( largeur > largeurmax ) largeurmax = largeur;
+	}
+  	
+  	// Controle que toutes les options obligatoire sont présentes dans la ligne d'argument
+  	for(int i=0 ; i < m_OptionList.size() ; i++ )
+  	{
+  		int largeur = m_OptionList[i].CommonName.size() + m_OptionList[i].Synonim.size();
+  		os << "      ";
+  		if ( m_OptionList[i].Obligatory == false ) os <<"[";
+  		else os << " ";
+  		os << m_OptionList[i].CommonName ;
+  		if (m_OptionList[i].Synonim.empty() == false )
+  		{
+  			os << "|"<<m_OptionList[i].Synonim;	
+  		}
+  		if ( m_OptionList[i].Obligatory == false ) os <<"]";
+  		else os << " ";
+  		//Aligne le texte avec la différence en blanc
+  		for (int b=largeur ; b< largeurmax ; b++) os <<" ";
+  		os <<   "  :  "<<m_OptionList[i].Description;
+  		if (m_OptionList[i].NumberOfParametersFixed == true ) os << "  ("<<m_OptionList[i].NumberOfParameters<<" parametres)";
+  		else os << "  (N parametres)";
+  		os << std::endl;
+	}
+	os << std::endl;
 }
 
-const char * 
-CommandLineArgumentParseResult
-::GetOptionParameter(const char *option, unsigned int number)
-{
-  assert(IsOptionPresent(option));
-  assert(number < m_OptionMap[std::string(option)].size());
-
-  return m_OptionMap[std::string(option)][number].c_str();
-}
 
 
-void  
-CommandLineArgumentParseResult
-::Clear()
-{
-  m_OptionMap.clear();
-}
-
-void  
-CommandLineArgumentParseResult
-::AddOption(const std::string &option, int nParms)
-{
-  ParameterArrayType pat;
-  pat.reserve(nParms);
-  m_OptionMap[option] = pat;
-}
-
-void  
-CommandLineArgumentParseResult
-::AddParameter(const std::string &option, const std::string &parameter)
-{
-  m_OptionMap[option].push_back(parameter);  
-}
 
 }
 
diff --git a/Code/Common/otbCommandLineArgumentParser.h b/Code/Common/otbCommandLineArgumentParser.h
index 271c55c87b..200b612824 100755
--- a/Code/Common/otbCommandLineArgumentParser.h
+++ b/Code/Common/otbCommandLineArgumentParser.h
@@ -17,16 +17,19 @@
 #pragma warning ( disable : 4503 )
 #endif
 
+#include <iostream>
 #include <vector>
 #include <string>
-#include <list>
 #include <map>
 
-#include "itkIndent.h"
+//#include "itkIndent.h"
 
 namespace otb
 {
 
+
+//class CommandLineArgumentParser;
+
 /**
  * \class CommandLineArgumentParseResult
  * \brief Objet retourné par lCommandLineArgumentParser
@@ -36,23 +39,28 @@ class CommandLineArgumentParseResult
 {
 public:
   /** Check whether the option was passed in or not */
-  bool IsOptionPresent(const char *option);
+  bool IsOptionPresent(const char *option) const;
 
   /** Get one of the parameters to the option */
-  const char *GetOptionParameter(const char *option, unsigned int number = 0);
-  
+//  const char *GetOptionParameter(const char *option, unsigned int number = 0);
+  int GetNumberOfParameters(const char *option);
+
   void PrintSelf(std::ostream& os/*, itk::Indent indent*/) const;
 
+
   template< typename TypeValeur >
-  TypeValeur GetOptionParameterNumericValue(const char *option, unsigned int number)const;
+  TypeValeur GetParameter(const char *option, unsigned int number=0)const;
 
+  std::string GetStringParameter(const char *option, unsigned int number=0) const;
 
 private:
+
+
   typedef std::vector< std::string > ParameterArrayType;
-  typedef std::map< std::string, ParameterArrayType> OptionMapType;
+  typedef std::map< std::string, ParameterArrayType > OptionMapType;
 
   void Clear();
-  void AddOption(const std::string &option, int nParms);
+  void AddOption(const std::string &option/*, int nParms*/);
   void AddParameter(const std::string &option, const std::string &parameter);
 
   OptionMapType m_OptionMap;
@@ -85,40 +93,56 @@ class CommandLineArgumentParser
 {
 public:
   /** Add an option with 0 or more parameters (words that follow it) */
-  void AddOption(const char *name, const int nParameters, const char * comment);
+//  void AddOption(const char *name, const int nParameters, const char * comment);
+  // Au moins une valeur
+
+  void AddOption(const char *name, const  char * comment, char *synonim = NULL, int nParameters = 1, bool obligatory =true);
+  // Si -1, alors on ne connait pas le nombre de parametres à l'avance.
+  void AddOptionNParams(const char *name, const char * comment, char *synonim = NULL, bool obligatory =true);
   
   /** Add a different string that envokes the same option (--file and -f) */  
-  void AddSynonim(const char *option, const char *synonim);
+//  void AddSynonim(const char *option, const char *synonim);
 
-  /** Try processing a command line.  Returns false if something breaks */
-  bool TryParseCommandLine(int argc, char *argv[], 
+  void ParseCommandLine(int argc, char *argv[], 
                            CommandLineArgumentParseResult &outResult,
                            bool failOnUnknownTrailingParameters = true);
 
+private:
+
   void PrintUsage(std::ostream& os/*, itk::Indent indent*/) const;
+  bool FindOption(const std::string & , int & index);
+
+  /** Try processing a command line.  Returns false if something breaks */
+  bool TryParseCommandLine(int argc, char *argv[], 
+                           CommandLineArgumentParseResult &outResult,
+                           bool failOnUnknownTrailingParameters );
 
-private:
-  // Synonim list type
-  typedef std::list< std::string > NameListType;
   typedef struct 
     {
-    std::string CommonName;
-    std::string CommentName;
-    unsigned int NumberOfParameters;
+    std::string CommonName;             //Nom identifiant cette option
+    std::string Description;            //Description de l'option
+    std::string Synonim;                //Chaine synonim = raccourci
+    bool NumberOfParametersFixed;       //Precise si le nombre de valeurs attendues est connu
+    int NumberOfParameters;	        //Nombre de valeurs pour cette option
+    bool Obligatory;                    //Precise si l'option est obligatoire
+    bool Finded;                        //Precise si l'option a été trouvée dans la ligne de commande
     } OptionType;
-  typedef std::map< std::string, OptionType> OptionMapType;
+//  typedef std::map< std::string, OptionType> OptionMapType;
+  typedef std::vector< OptionType> ListOptionType;
   
-  OptionMapType m_OptionMap;
+  ListOptionType m_OptionList;
 
 
   std::string m_ProgramName;
 };
 
 
+
+}
+
 #ifndef OTB_MANUAL_INSTANTIATION
 #include "otbCommandLineArgumentParser.txx"
 #endif
 
-}
 
 #endif // __otbCommandLineArgumentParser_h_
diff --git a/Code/Common/otbCommandLineArgumentParser.txx b/Code/Common/otbCommandLineArgumentParser.txx
index 31510b34ae..e68dbd5ca5 100755
--- a/Code/Common/otbCommandLineArgumentParser.txx
+++ b/Code/Common/otbCommandLineArgumentParser.txx
@@ -1,28 +1,28 @@
-#ifndef _otbCommandLineArgumentParser_txx
-#define _otbCommandLineArgumentParser_txx
-
-#include "otbCommandLineArgumentParser.h"
-
-#include "itkMacro.h"
-
-namespace otb
-{
-
-
-template< typename TypeValeur >
-TypeValeur
-CommandLineArgumentParseResult
-::GetOptionParameterNumericValue(const char *option, unsigned int number)const
-{
-  const char * parametre = this->GetOptionParameter(option, number);
-  TypeValeur lValeur;
-  ::itk::OStringStream flux;
-  flux << parametre;
-  flux >> lValeur;
-  return lValeur;
-}
-
-
-} // end namespace otb
-
-#endif
+#ifndef _otbCommandLineArgumentParser_txx
+#define _otbCommandLineArgumentParser_txx
+
+#include "otbCommandLineArgumentParser.h"
+
+#include "itkMacro.h"
+
+namespace otb
+{
+
+
+template< typename TypeValeur >
+TypeValeur
+CommandLineArgumentParseResult
+::GetParameter(const char *option, unsigned int number)const
+{
+  std::string parametre = this->GetStringParameter(option, number);
+  TypeValeur lValeur;
+  ::itk::OStringStream flux;
+//  flux << parametre;
+//  flux >> lValeur;
+  return lValeur;
+}
+
+
+} // end namespace otb
+
+#endif
diff --git a/Testing/Code/Common/otbTestCommandLineArgumentParser.cxx b/Testing/Code/Common/otbTestCommandLineArgumentParser.cxx
index 7dd300286a..bfc364b98b 100755
--- a/Testing/Code/Common/otbTestCommandLineArgumentParser.cxx
+++ b/Testing/Code/Common/otbTestCommandLineArgumentParser.cxx
@@ -21,28 +21,35 @@ int otbTestCommandLineArgumentParser( int argc, char ** argv )
     { 
         // Parse command line parameters
         otb::CommandLineArgumentParser parser;
+  void AddOption(const char *name, const  char * comment, char *synonim = NULL, int nParameters = 1, bool obligatory =true);
+  // Si -1, alors on ne connait pas le nombre de parametres à l'avance.
+  void AddOptionNParams(const char *name, const char * comment, char *synonim = NULL, bool obligatory =true);
   
-        parser.AddOption("-image",1,"Nom d'une image");
-        parser.AddOption("-entier",1,"Valeur entiere");
-        parser.AddSynonim("-entier","-e");
-        parser.AddOption("-deuxentiers", 2,"Liste de deux entiers");
-        parser.AddOption("-double", 1,"Valeur réelle double");
-        parser.AddSynonim("-double", "-d");
-        parser.AddOption("-float",1,"Valeur réelle double");
-        parser.AddSynonim("-float","-f");
-        parser.AddOption("-help",0,"");
-        parser.AddSynonim("-help","-h");
+        parser.AddOption("-image","Nom d'une image","-i",1,true);
+        parser.AddOption("-entier","Une Valeur entiere (obligatoire)","-e");
+        parser.AddOption("-deuxentiers","Deux Valeurs entieres non obligatoire","",2,false);
+        parser.AddOption("-double", "Valeur réelle double");
+        parser.AddOptionNParams("-doubles", "Liste de Valeurs réelles","-ld");
   
         otb::CommandLineArgumentParseResult parseResult;
   
-        if(!parser.TryParseCommandLine(argc,argv,parseResult) || parseResult.IsOptionPresent("-help"))
+        parser.ParseCommandLine(argc,argv,parseResult) ;//|| parseResult.IsOptionPresent("-help"))
+
+
+        std::cout << "Image : "<<parseResult.GetStringParameter("-image")<<std::endl;
+        unsigned int lEntier = parseResult.GetParameter<unsigned int>("-entier");
+        std::cout << "Entier : "<<lEntier<<std::endl;
+        unsigned int lEntierDeux = parseResult.GetParameter<unsigned int>("-deuxentiers",1);
+        std::cout << "Entier : "<<lEntier<<std::endl;
+        double lDouble = parseResult.GetParameter<double>("-double");
+        std::cout << "Double : "<<lDouble<<std::endl;
+        std::cout << "List de Double : "<<parseResult.GetNumberOfParameters("-double")<<std::endl;
+        for (int i =0 ; i<parseResult.GetNumberOfParameters("-double") ; i++)
         {
-                parser.PrintUsage(std::cout);
-                return EXIT_FAILURE;
+                double value = parseResult.GetParameter<double>("-double",i);
+                std::cout << "  "<<value;
         }
-        
-        parseResult.PrintSelf(std::cout);
-        
+        std::cout << std::endl;
     } 
 
   catch( itk::ExceptionObject & err ) 
-- 
GitLab