838 lines
25 KiB
C++
838 lines
25 KiB
C++
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/* eoParser.h
|
|
some classes to parser either the command line or a parameter file
|
|
|
|
(c) Marc Schoenauer and Geneura team, 1999
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
|
*/
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _PARSER_H
|
|
#define _PARSER_H
|
|
|
|
#include <string.h> // for strcasecmp ... maybe there's a c++ way of doing it?
|
|
// Yep there is, but needs either a simple functor for the equal function
|
|
// or a hand-rolled std::string template class (this isn't that horrible as
|
|
// it sounds, it just means a new std::string_traits class with two changed
|
|
// function definitions. (Maarten)
|
|
#ifdef _MSC_VER
|
|
#define strcasecmp(a,b) _strnicmp(a,b,strlen(a))
|
|
#endif
|
|
|
|
// STL includes
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <strstream>
|
|
#include <ctime>
|
|
|
|
// include for std::exceptions
|
|
#include <stdexcept> // std::logic_error
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Class Param
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/**
|
|
* A param repesents an argument that can be passed to a program in the command line
|
|
*/
|
|
class Param {
|
|
public:
|
|
|
|
/**
|
|
* Type of params
|
|
*/
|
|
enum valueType { INT, UL, FLOAT, STRING, BOOL, ARRAY, TITLE };
|
|
|
|
/**
|
|
* Construct an Param.
|
|
* @param _shortName Short name of the argument
|
|
* @param _longName Long name of the argument
|
|
* @param _default The default value
|
|
* @param _valueType Type of the parameter ("integer","unsigned long", "float","char", "bool" and so on)
|
|
* @param _description Description of the parameter. What is useful for.
|
|
* @param _required If it is a necessary parameter or not
|
|
*/
|
|
Param (std::string _shortName="-h", std::string _longName="--help",
|
|
std::string _default = "", valueType _valType= STRING,
|
|
std::string _description="Shows this help",
|
|
bool _required=false )
|
|
: repShortName(_shortName), repLongName(_longName),
|
|
repDescription(_description ), repEnv(""), repDefault(_default),
|
|
repValue(_default), repValType( _valType),
|
|
repRequired( _required), repChanged(false) {
|
|
|
|
const char *c = repLongName.c_str();
|
|
for(unsigned i=0; i<repLongName.length() ; i++,c++) {
|
|
if( *c != '-' ) break;
|
|
}
|
|
//initialize "repEnv" depending on the long name of the parameter.
|
|
//previously the "-" (if exist) are skiped.
|
|
repEnv = c ;
|
|
};
|
|
|
|
/**
|
|
* Copy constructor
|
|
* @param _param The source param.
|
|
*/
|
|
Param (const Param& _param) :
|
|
repShortName(_param.repShortName), repLongName(_param.repLongName),
|
|
repDescription(_param.repDescription ), repEnv(_param.repEnv),
|
|
repDefault(_param.repDefault),
|
|
repValue(_param.repValue), repValType(_param.repValType),
|
|
repRequired(_param.repRequired), repChanged(_param.repChanged) {};
|
|
|
|
/**
|
|
* Virtual destructor is needed.
|
|
*/
|
|
virtual ~Param () {};
|
|
|
|
/**
|
|
* Returns the short name.
|
|
*/
|
|
const std::string& shortName ( void ) const { return repShortName; };
|
|
|
|
/**
|
|
* Returns the long name.
|
|
*/
|
|
const std::string& longName ( void ) const { return repLongName; };
|
|
|
|
/**
|
|
* Returns the description of the argument
|
|
*/
|
|
const std::string& description ( void ) const { return repDescription; };
|
|
|
|
/**
|
|
* Returns the environment variable of the argument
|
|
*/
|
|
const std::string& environment ( void ) const { return repEnv; };
|
|
|
|
/**
|
|
* Returns the default value of the argument
|
|
*/
|
|
const std::string& defValue ( void ) const { return repDefault; };
|
|
|
|
/**
|
|
* Sets a value for the param.
|
|
* @param _value The new value.
|
|
*/
|
|
void value ( const std::string& _value ) { repValue = _value; repChanged = true; };
|
|
|
|
/**
|
|
* Returns the value of the param.
|
|
*/
|
|
const std::string& value ( void ) const { return repValue; };
|
|
|
|
/**
|
|
* Returns if required or not.
|
|
*/
|
|
bool required ( void ) const { return repRequired; };
|
|
|
|
/**
|
|
* Returns the type of the param's value.
|
|
*/
|
|
Param::valueType valType( void ) const { return repValType; };
|
|
|
|
/**
|
|
* Returns true if the default value of the param has changed.
|
|
*/
|
|
bool changed( void ) const { return repChanged; };
|
|
|
|
private:
|
|
std::string repShortName;
|
|
std::string repLongName;
|
|
std::string repDescription;
|
|
std::string repEnv;
|
|
std::string repDefault;
|
|
|
|
std::string repValue;
|
|
Param::valueType repValType;
|
|
bool repRequired;
|
|
bool repChanged;
|
|
};
|
|
|
|
/// This operator is defined to avoid errors in some systems
|
|
inline bool operator < ( const Param& _p1, const Param& _p2 ) {
|
|
return ( _p1.shortName() < _p2.shortName() );
|
|
}
|
|
|
|
/// This operator is defined to avoid errors in some systems
|
|
inline bool operator == ( const Param& _p1, const Param& _p2 ) {
|
|
return ( _p1.shortName() == _p2.shortName() );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Class Parser
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Parses the command line / input parameter file / environment variables.
|
|
*/
|
|
class Parser {
|
|
public:
|
|
|
|
/**
|
|
* Constructor
|
|
* @param _argc, _ argv command line arguments
|
|
* @param _programDescription Description of the work the program does
|
|
*/
|
|
Parser ( int _argc, char **_argv , std::string _programDescription,
|
|
std::string _sFileParamName = "-P",
|
|
std::string _lFileParamName = "--Param") :
|
|
params(),
|
|
programName( _argv[0]), programDescription( _programDescription),
|
|
parse_argc(_argc), parse_argv(_argv), InputFileName("") {
|
|
|
|
// the input file name has to be read immediately - from command-line or environement (not input0file :-)
|
|
std::string _default = _argv[0];
|
|
_default += ".param";
|
|
Param param (_sFileParamName, _lFileParamName, _default, Param::STRING, "Name of the input file", 0);
|
|
|
|
// FIRST: look for the corresponding environment variable
|
|
if( getenv( param.environment().c_str() ) )
|
|
param.value(getenv(param.environment().c_str()) );
|
|
|
|
// LAST (highest priority) parse the command line arguments
|
|
for (int i=1 ; i<parse_argc ; i++)
|
|
if( ( ! strcasecmp(param.longName().c_str(), parse_argv[i]) ) ||
|
|
( ! strcmp(param.shortName().c_str(), parse_argv[i]) )
|
|
) { // found the parameter name
|
|
param.value(parse_argv[i+1]);
|
|
break;
|
|
}
|
|
// Now try to open the file
|
|
ifstream is(param.value().c_str());
|
|
if (is) // file exists ???
|
|
InputFileName = param.value().c_str();
|
|
|
|
params.push_back( param );
|
|
};
|
|
|
|
/**
|
|
* Copy constructor
|
|
* @param _parser The source parser
|
|
*/
|
|
Parser ( const Parser& _parser ) :
|
|
params(_parser.params),
|
|
programName( _parser.programName),
|
|
programDescription(_parser.programDescription),
|
|
parse_argc(_parser.parse_argc),
|
|
parse_argv(_parser.parse_argv),
|
|
InputFileName(_parser.InputFileName)
|
|
{};
|
|
|
|
/**
|
|
* Virtual destructor is needed.
|
|
*/
|
|
virtual ~Parser () {};
|
|
|
|
|
|
/**
|
|
* Adds a fake parameter == title in the output file
|
|
* @param the title
|
|
*/
|
|
void AddTitle (const std::string& _title)
|
|
{
|
|
Param param ( "", "", "", Param::TITLE, _title, false );
|
|
params.push_back( param );
|
|
}
|
|
|
|
/**
|
|
* Description of all parameter readings:
|
|
* @param _shortName Short name of the param.
|
|
* @param _longName Long name of the param.
|
|
* @param _default Default value.
|
|
* @param _valType Type of the parameter
|
|
* @param _description Parameter utility
|
|
* @param _required If the parameter is necessary or not
|
|
*/
|
|
|
|
/**
|
|
* Gets the std::string value of a param from the full parameter description
|
|
* @param see above
|
|
*/
|
|
std::string getString (const std::string& _shortName, const std::string& _longName,
|
|
const std::string& _default = "",
|
|
const std::string& _description="", bool _required=false) {
|
|
Param param ( _shortName, _longName, _default, Param::STRING, _description, _required );
|
|
parse( param );
|
|
params.push_back( param );
|
|
|
|
return param.value();
|
|
};
|
|
|
|
/**
|
|
* Gets the bool value of a param-flag from the full parameter description
|
|
* @param see above
|
|
*/
|
|
|
|
bool getBool (const std::string& _shortName, const std::string& _longName,
|
|
const std::string& _description="") {
|
|
Param param ( _shortName, _longName, "false", Param::BOOL, _description, false );
|
|
parse( param );
|
|
params.push_back( param );
|
|
|
|
if (param.value() == "true") {
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Gets the "array" (std::vector of std::strings) value of a param from the full parameter description
|
|
* @param see above
|
|
*/
|
|
std::vector<std::string> getArray (const std::string& _shortName, const std::string& _longName,
|
|
const std::string& _default = "",
|
|
const std::string& _description="", bool _required=false) {
|
|
Param param ( _shortName, _longName, _default, Param::ARRAY, _description, _required );
|
|
parse( param );
|
|
params.push_back( param );
|
|
|
|
istrstream is(param.value().c_str());
|
|
std::vector<std::string> retValue;
|
|
std::string tmpStr;
|
|
|
|
is >> tmpStr;
|
|
while(is){
|
|
retValue.push_back(tmpStr);
|
|
is >> tmpStr;
|
|
}
|
|
return retValue;
|
|
};
|
|
|
|
/**
|
|
* Gets the int value of a param given the full description of the parameter
|
|
* @param see above
|
|
* @std::exception BadType if the param's value isn't a correct int
|
|
*/
|
|
|
|
int getInt (const std::string& _shortName, const std::string& _longName,
|
|
const std::string& _default = "",
|
|
const std::string& _description="", bool _required=false) {
|
|
Param param ( _shortName, _longName, _default, Param::INT, _description, _required );
|
|
parse( param );
|
|
params.push_back( param );
|
|
|
|
// now gets the value
|
|
istrstream is( param.value().c_str());
|
|
int retValue;
|
|
is >> retValue;
|
|
|
|
if (!is) {
|
|
throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float");
|
|
return 0;
|
|
} else {
|
|
return retValue;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Gets the unsigned lon value of a param given ...
|
|
* @param see above
|
|
* @std::exception BadType if the param's value isn't a correct unsigned long
|
|
*/
|
|
|
|
int getUnsignedLong (const std::string& _shortName, const std::string& _longName,
|
|
const std::string& _default = "",
|
|
const std::string& _description="", bool _required=false) {
|
|
Param param ( _shortName, _longName, _default, Param::UL, _description, _required );
|
|
parse( param );
|
|
params.push_back( param );
|
|
|
|
// now gets the value
|
|
istrstream is( param.value().c_str());
|
|
unsigned long retValue;
|
|
is >> retValue;
|
|
|
|
if (!is) {
|
|
throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float");
|
|
return 0;
|
|
} else {
|
|
return retValue;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Gets the float value of a param given the description of the parameter
|
|
* @param see above
|
|
* @std::exception BadType if the param's value isn't a correct int
|
|
*/
|
|
|
|
float getFloat (const std::string& _shortName, const std::string& _longName,
|
|
const std::string& _default = "",
|
|
const std::string& _description="", bool _required=false) {
|
|
Param param ( _shortName, _longName, _default, Param::FLOAT, _description, _required );
|
|
parse( param );
|
|
params.push_back( param );
|
|
|
|
// now gets the value
|
|
istrstream is( param.value().c_str());
|
|
float retValue;
|
|
is >> retValue;
|
|
|
|
if (!is) {
|
|
throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float");
|
|
return 0;
|
|
} else {
|
|
return retValue;
|
|
}
|
|
};
|
|
|
|
|
|
std::string parse_std::string (std::istream & _is) {
|
|
std::string paramValue;
|
|
_is >> paramValue;
|
|
//if the first character of the std::string or array is not a " => just one word or array-element.
|
|
if( paramValue[0] != '\"' )
|
|
return paramValue;
|
|
|
|
if( paramValue[1] == '\"' ) // the empty std::string
|
|
return "" ;
|
|
|
|
//else => read until the next " (the end of the std::string).
|
|
const char *c = paramValue.c_str();
|
|
std::string tmpStr = c+1;// skip the "
|
|
if (tmpStr[tmpStr.length()-1] == '\"') { // one word only
|
|
//tmpStr[tmpStr.length()-1] = '\0';
|
|
tmpStr.erase( &tmpStr[tmpStr.length()-1] );
|
|
return tmpStr;
|
|
}
|
|
|
|
bool stop = false;
|
|
while (_is && !stop) {
|
|
_is >> paramValue;
|
|
// test last character of paramValue for "
|
|
if (paramValue[paramValue.length()-1] == '\"') {
|
|
paramValue.erase( ¶mValue[paramValue.length()-1] );
|
|
//paramValue[paramValue.length()-1] = '\0';
|
|
stop = true;
|
|
}
|
|
tmpStr = tmpStr + " " + paramValue ;
|
|
}
|
|
return tmpStr;
|
|
};
|
|
|
|
|
|
void parse (Param & param) {
|
|
int i;
|
|
std::string tmpStr, ReadStr, FirstWord;
|
|
|
|
// FIRST: look if the associated environment variables have any value, to use them.
|
|
if( getenv( param.environment().c_str() ) ) {
|
|
//std::cout <<"\t\t ENV param: ,"<<p->shortName()<<", ,"<<getenv(p->environment().c_str())<<std::endl;
|
|
param.value(getenv(param.environment().c_str()) );
|
|
}
|
|
|
|
|
|
// SECOND: search the file parameter, if present
|
|
if ( InputFileName != "" ) {
|
|
ifstream is(InputFileName.c_str());
|
|
while (is) {
|
|
is >> tmpStr;
|
|
if ( ( !strcmp(tmpStr.c_str(), param.shortName().c_str()) ) ||
|
|
( !strcasecmp(tmpStr.c_str(), param.longName().c_str()) )
|
|
) { // found the keyword
|
|
|
|
Param::valueType tmp = param.valType();
|
|
switch ( tmp ) {
|
|
case Param::TITLE:
|
|
std::cerr << "Error, we should not be there" << std::endl;
|
|
exit(1);
|
|
break;
|
|
case Param::BOOL :
|
|
param.value("true" );
|
|
break;
|
|
|
|
case Param::INT:
|
|
case Param::UL:
|
|
case Param::FLOAT:
|
|
is >> tmpStr;
|
|
param.value(tmpStr);
|
|
break;
|
|
|
|
case Param::STRING:
|
|
tmpStr = parse_std::string(is);
|
|
param.value(tmpStr);
|
|
break;
|
|
|
|
case Param::ARRAY:
|
|
ReadStr = parse_std::string(is);
|
|
if ( ReadStr != "<" ) { // no "<" ">" --> a single std::string in the array
|
|
param.value(ReadStr);
|
|
break;
|
|
}
|
|
// read next word - and keep it in case of <> mismatch
|
|
FirstWord = parse_std::string(is);
|
|
// test for empty array
|
|
if (FirstWord == ">") {
|
|
param.value("");
|
|
break;
|
|
}
|
|
// else, read all words until ">"
|
|
tmpStr = FirstWord;
|
|
ReadStr = parse_std::string(is);
|
|
while ( is && (ReadStr != ">") ) {
|
|
tmpStr = tmpStr + " " + ReadStr;
|
|
ReadStr = parse_std::string(is);
|
|
}
|
|
|
|
if (!is) { // there was a "<" without the corresponding ">"
|
|
throw Parser::BadArrayParam( param.longName(), FirstWord );
|
|
param.value(FirstWord); // assume unique std::string
|
|
}
|
|
else
|
|
param.value(tmpStr);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// LAST (highest priority) parse the command line arguments
|
|
for (i=1 ; i<parse_argc ; i++)
|
|
if( ( ! strcasecmp(param.longName().c_str(), parse_argv[i]) ) ||
|
|
( ! strcmp(param.shortName().c_str(), parse_argv[i]) )
|
|
) { // found the parameter name
|
|
if (param.valType() == Param::BOOL) {
|
|
//std::cout <<"BOOL: "<<parse_argv[i]<<" <-- true"<<std::endl;
|
|
param.value("true");
|
|
}else{
|
|
if (param.valType() != Param::ARRAY) { //only if it is not an array
|
|
//std::cout <<"TYPE: "<<parse_argv[i]<<" <-- "<<parse_argv[i+1]<<std::endl;
|
|
param.value(parse_argv[i+1]);
|
|
}else{ //if it is an ARRAY
|
|
i++;
|
|
ReadStr = parse_argv[i++];
|
|
//std::cout <<"ARRAY: <-- ";
|
|
|
|
if ( ReadStr != "<" ) { // no "<" ">" --> a single std::string in the array
|
|
param.value(ReadStr);
|
|
}else{
|
|
// read next word - and keep it in case of <> mismatch
|
|
FirstWord = parse_argv[i++];
|
|
|
|
// test for empty array
|
|
if (FirstWord == ">") {
|
|
param.value("");
|
|
}else{
|
|
// else, read all words until ">"
|
|
tmpStr = FirstWord;
|
|
ReadStr = parse_argv[i++];
|
|
while ( (i<parse_argc) && (ReadStr != ">") ) {
|
|
tmpStr = tmpStr + " " + ReadStr;
|
|
ReadStr = parse_argv[i++];
|
|
}
|
|
//std::cout <<"tmpStr ;"<<tmpStr<<"; ("<<i<<","<<parse_argc<<") "<<std::endl;
|
|
|
|
if ( (i>=parse_argc) && (ReadStr != ">") ) { // there was a "<" without the corresponding ">"
|
|
throw Parser::BadArrayParam( param.longName(), FirstWord );
|
|
param.value(FirstWord); // assume unique std::string
|
|
}else{
|
|
param.value(tmpStr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
//MS after trying all possibilities, and if the value has not changed
|
|
// though the parameter was required, protest!
|
|
if (param.required() && !param.changed())
|
|
throw Parser::MissingReqParam(param.shortName());
|
|
|
|
};
|
|
|
|
/**
|
|
* Sets a new value for a param given its short name or its long name.
|
|
* @param _name One of the names of the param.
|
|
* @param _value Value to be assigned.
|
|
* @std::exception UnknownArg if the param doesn't exist
|
|
* @std::exception MissingVal if the param hasn't got a value
|
|
*/
|
|
Param::valueType setParamValue (const std::string& _name, const char* _value){
|
|
std::vector<Param>::iterator pos;
|
|
|
|
for (pos=params.begin() ; pos!=params.end() ; pos++)
|
|
if (pos->shortName()==_name || pos->longName()==_name)
|
|
break;
|
|
|
|
// if found ...
|
|
if (pos!=params.end()) {
|
|
switch ( pos->valType() ) {
|
|
case Param::TITLE:
|
|
std::cerr << "Error, we should not be there" << std::endl;
|
|
exit(1);
|
|
break;
|
|
case Param::BOOL :
|
|
pos->value("true");
|
|
break;
|
|
case Param::ARRAY :
|
|
case Param::INT:
|
|
case Param::UL:
|
|
case Param::FLOAT:
|
|
case Param::STRING:
|
|
if (_value != NULL){
|
|
pos->value(_value);
|
|
}else{
|
|
throw Parser::MissingVal(_name);
|
|
return Param::BOOL;
|
|
}
|
|
break;
|
|
} // switch
|
|
|
|
return pos->valType();
|
|
|
|
}else{
|
|
throw Parser::UnknownArg(_name);
|
|
return Param::BOOL;
|
|
}
|
|
};
|
|
|
|
/// the output method - generate the .status file (unless other name is given)
|
|
friend std::ostream & operator<< ( std::ostream & os, Parser & _parser )
|
|
{
|
|
std::vector<Param>::iterator p;
|
|
//print every param with its value
|
|
for ( p=_parser.params.begin(); p!=_parser.params.end(); p++ ) {
|
|
switch ( p->valType() ) {
|
|
case Param::BOOL :
|
|
if( p->value() == (std::string) "true")
|
|
os << p->longName();
|
|
else
|
|
os << "#" << p->longName() ; // so the name of the bool is commented out
|
|
break;
|
|
|
|
case Param::INT:
|
|
case Param::UL:
|
|
case Param::FLOAT:
|
|
os << p->longName()<<" "<<p->value();
|
|
break;
|
|
|
|
case Param::ARRAY :
|
|
os << p->longName() << " < " << p->value().c_str() << " >" ;
|
|
break;
|
|
case Param::STRING:
|
|
os << p->longName()<<" \""<<p->value().c_str()<<"\" ";
|
|
break;
|
|
case Param::TITLE:
|
|
os << std::endl; // Title is in the description below
|
|
break;
|
|
} // switch
|
|
os << "\t #" << p->shortName() << " : " << p->description();
|
|
if (p->valType() != Param::TITLE)
|
|
os << " [" << p->defValue() << "]" ;
|
|
os << std::endl;
|
|
}
|
|
return os;
|
|
};
|
|
|
|
/**
|
|
* Prints out the std::list of parameters in the output file (if specified)
|
|
*/
|
|
void outputParam(std::string _OutputFile="")
|
|
{
|
|
if (_OutputFile == "") {
|
|
_OutputFile = parse_argv[0];
|
|
_OutputFile += ".status";
|
|
}
|
|
|
|
std::ofstream os(_OutputFile.c_str());
|
|
os << "Parameters used by \"" << programName << "\" ("
|
|
<< programDescription << ")" << std::endl << std::endl;
|
|
os << *this;
|
|
};
|
|
|
|
/**
|
|
* Prints an automatic help in the standard output using the information
|
|
* provided by parameters
|
|
*/
|
|
void printHelp() {
|
|
std::vector<Param>::iterator p;
|
|
// unsigned i;
|
|
|
|
// print program name and description
|
|
std::cout << this->programName <<": "<<programDescription<<std::endl<<std::endl;
|
|
|
|
// print the usage when calling the program from the command line
|
|
std::cout << "Usage: "<< programName<<" [Options]\n";
|
|
// only short usage!
|
|
std::cout << "Options of the form \"-ShortName value\" or \"--LongName value\"" << std::endl;
|
|
|
|
// for ( i=0,p=params.begin(); p!=params.end(); i++,p++ )
|
|
// if( p->valType() != Param::TITLE ) {
|
|
// if( p->valType() != Param::BOOL ){
|
|
// std::cout << ( (!p->required())?"[":"");
|
|
// std::cout <<p->shortName()<<" value"<<i;
|
|
// std::cout << ( (!p->required())?"]":"")<<" ";
|
|
// }else{
|
|
// std::cout << "["<<p->shortName()<<"] ";
|
|
// }
|
|
// } // for p
|
|
std::cout << "Where:"<<std::endl;
|
|
|
|
for ( p=params.begin(); p!=params.end(); p++ ) {
|
|
if( p->valType() != Param::TITLE ) {
|
|
// Victor: 04-Jan-2000
|
|
// Modified because the - and -- prefixes are not needed.
|
|
/*
|
|
std::cout << "-" << p->shortName()
|
|
<<", --"<<p->longName()<<":\t"
|
|
<<p->description()<<std::endl;
|
|
*/
|
|
std::cout << p->shortName()
|
|
<<", " << p->longName()<<":\t"
|
|
<<p->description()<<std::endl;
|
|
std::cout << "\t(";
|
|
switch ( p->valType() ) {
|
|
case Param::INT: std::cout <<"Integer"; break;
|
|
case Param::UL: std::cout <<"Unsigned Long Integer"; break;
|
|
case Param::FLOAT: std::cout <<"Float"; break;
|
|
case Param::STRING: std::cout <<"String"; break;
|
|
case Param::ARRAY: std::cout <<"An array of std::strings, enclosed within < >"; break;
|
|
case Param::BOOL: std::cout << "Flag"; break;
|
|
case Param::TITLE: break;
|
|
} // switch
|
|
if(p->valType() == Param::BOOL)
|
|
std::cout << ") True if present" << std::endl;
|
|
else
|
|
std::cout<<") "<<( (p->required())?"Required":"Optional" )<<". By default: "<<p->defValue()<<std::endl;
|
|
}
|
|
else {
|
|
std::cout << "\n\t # " << p->description() << std::endl;
|
|
}
|
|
} // for p
|
|
std::cout << std::endl;
|
|
};
|
|
|
|
/**
|
|
* This class managges unknown argument std::exceptions.
|
|
*/
|
|
class UnknownArg : public std::logic_error {
|
|
public:
|
|
|
|
/**
|
|
* Constructor
|
|
* @param _arg std::string to be shown when the std::exception occurs
|
|
*/
|
|
UnknownArg( const std::string& _arg): std::logic_error( "Invalid argument: "+_arg ) { };
|
|
};
|
|
|
|
/**
|
|
* This class managges bad param types.
|
|
*/
|
|
class BadType : public std::logic_error {
|
|
public:
|
|
|
|
/**
|
|
* Constructor
|
|
* @param _param The param
|
|
* @param _value The value of the param
|
|
*/
|
|
BadType(const std::string& _param, const std::string& _value, const std::string& _correctType)
|
|
: std::logic_error("The value '" + _value + "' assigned to the argument " + _param + " isn't a correct "+_correctType) { };
|
|
};
|
|
|
|
/**
|
|
* This class managges std::exceptions produced when there isn't a value for a parameter.
|
|
*/
|
|
class MissingVal : public std::logic_error {
|
|
public:
|
|
|
|
/**
|
|
* Constructor
|
|
* @param _param The param
|
|
*/
|
|
MissingVal(const std::string& _param) : std::logic_error("Missing value for parameter " + _param) {};
|
|
};
|
|
|
|
/**
|
|
* This class managges std::exceptions produced when the user forgot a required parameter.
|
|
*/
|
|
class MissingReqParam : public std::logic_error {
|
|
public:
|
|
|
|
/**
|
|
* Constructor
|
|
* @param _shortName The param's short name
|
|
*/
|
|
MissingReqParam(const std::string& _shortName) : std::logic_error("Missing required parameter " + _shortName) {};
|
|
};
|
|
|
|
/**
|
|
* This class managges std::exceptions du to < without a > in array value
|
|
*/
|
|
class BadArrayParam : public std::logic_error {
|
|
public:
|
|
|
|
/**
|
|
* Constructor
|
|
* @param _param The param
|
|
* @param _first_word The first word read after the "<"
|
|
*/
|
|
BadArrayParam(const std::string& _param, const std::string &_first_word) :
|
|
std::logic_error("Array parameter " + _param + ": No matching > (" + _first_word
|
|
+ "... )") {};
|
|
};
|
|
|
|
void createParamFile( std::ostream& _os ) {
|
|
std::vector<Param>::iterator p;
|
|
for ( p=params.begin(); p!=params.end(); p++ ) {
|
|
switch( p->valType() ) {
|
|
case Param::TITLE:
|
|
_os << std::endl << "# -- ";
|
|
break;
|
|
case Param::BOOL:
|
|
_os << ((p->value()=="true" )?"":"#")
|
|
<< p->longName();
|
|
break;
|
|
case Param::STRING:
|
|
_os << p->longName()<<"\t\""<<p->value()<<"\"";
|
|
break;
|
|
case Param::ARRAY:
|
|
_os << p->longName()<<"\t< "<<p->value()<<" >";
|
|
break;
|
|
default:
|
|
_os << p->longName()<<"\t"<<p->value();
|
|
break;
|
|
} // switch
|
|
_os << "\t #" << p->description() << std::endl;
|
|
}
|
|
}
|
|
private:
|
|
std::vector<Param> params;
|
|
std::string programName;
|
|
std::string programDescription;
|
|
int parse_argc;
|
|
char **parse_argv;
|
|
std::string InputFileName;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|