Newer
Older
Tomáš Oberhuber
committed
/***************************************************************************
tnlParameterContainer.cpp - description
-------------------
begin : 2007/06/15
copyright : (C) 2007 by Tomas Oberhuber
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <ctype.h>
#include <cstring>
#include <stdio.h>
Tomáš Oberhuber
committed
#include "tnlParameterContainer.h"
Tomáš Oberhuber
committed
bool matob( const char* value, bool& ret_val )
{
if( strcasecmp( value, "yes" ) == 0 ||
strcasecmp( value, "true" ) == 0 )
{
ret_val = true;
return true;
}
if( strcasecmp( value, "no" ) == 0 ||
strcasecmp( value, "false" ) == 0 )
{
ret_val = false;
return true;
}
return false;
}
tnlParameterContainer::
tnlParameterContainer()
Tomáš Oberhuber
committed
{
}
bool
tnlParameterContainer::
addParameter( const tnlString& name,
const tnlString& value )
Tomáš Oberhuber
committed
{
return parameters. Append( new tnlParameter< tnlString >( name, ::getType< tnlString >().getString(), tnlString( value ) ) );
Tomáš Oberhuber
committed
}
bool
tnlParameterContainer::
setParameter( const tnlString& name,
const tnlString& value )
Tomáš Oberhuber
committed
{
int i;
for( i = 0; i < parameters. getSize(); i ++ )
{
if( parameters[ i ] -> name == name )
{
if( parameters[ i ] -> type == ::getType< tnlString >() )
Tomáš Oberhuber
committed
{
( ( tnlParameter< tnlString > * ) parameters[ i ] )->value = value;
Tomáš Oberhuber
committed
return true;
}
else
{
cerr << "Parameter " << name << " already exists with different type "
<< parameters[ i ] -> type << " not "
<< ::getType< tnlString>() << endl;
Tomáš Oberhuber
committed
abort();
return false;
}
}
}
return addParameter( name, value );
Tomáš Oberhuber
committed
};
bool
tnlParameterContainer::
checkParameter( const tnlString& name ) const
Tomáš Oberhuber
committed
{
int i;
const int parameters_num = parameters. getSize();
for( i = 0; i < parameters_num; i ++ )
if( parameters[ i ] -> name == name ) return true;
return false;
}
tnlParameterContainer::
~tnlParameterContainer()
Tomáš Oberhuber
committed
{
parameters. DeepEraseAll();
}
Tomáš Oberhuber
committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
void tnlParameterContainer :: MPIBcast( int root, MPI_Comm mpi_comm )
{
#ifdef HAVE_MPI
int i;
int size = parameters. getSize();
:: MPIBcast( size, 1, root, mpi_comm );
for( i = 0; i < size; i ++ )
{
if( MPIGetRank() == root )
{
tnlParameterBase* param = parameters[ i ];
param -> type. MPIBcast( root, MPI_COMM_WORLD );
param -> name. MPIBcast( root, MPI_COMM_WORLD );
if( param -> type == "mString" )
{
( ( tnlParameter< tnlString >* ) param ) -> value. MPIBcast( root, mpi_comm );
}
if( param -> type == "bool" )
{
:: MPIBcast( ( ( tnlParameter< bool >* ) param ) -> value, 1, root, mpi_comm );
}
if( param -> type == "int" )
{
:: MPIBcast( ( ( tnlParameter< int >* ) param ) -> value, 1, root, mpi_comm );
}
if( param -> type == "double" )
{
:: MPIBcast( ( ( tnlParameter< double >* ) param ) -> value, 1, root, mpi_comm );
}
}
else
{
tnlString param_type, param_name;
param_type. MPIBcast( root, MPI_COMM_WORLD );
param_name. MPIBcast( root, MPI_COMM_WORLD );
if( param_type == "mString" )
{
tnlString val;
val. MPIBcast( root, mpi_comm );
addParameter< tnlString >( param_name. getString(),
Tomáš Oberhuber
committed
val );
}
if( param_type == "bool" )
{
bool val;
:: MPIBcast( val, 1, root, mpi_comm );
addParameter< bool >( param_name. getString(),
Tomáš Oberhuber
committed
val );
}
if( param_type == "int" )
{
int val;
:: MPIBcast( val, 1, root, mpi_comm );
addParameter< int >( param_name. getString(),
Tomáš Oberhuber
committed
val );
}
if( param_type == "double" )
{
double val;
:: MPIBcast( val, 1, root, mpi_comm );
addParameter< double >( param_name. getString(),
Tomáš Oberhuber
committed
val );
}
}
}
#endif
}
bool
parseCommandLine( int argc, char* argv[],
const tnlConfigDescription& config_description,
tnlParameterContainer& parameters,
bool printUsage )
Tomáš Oberhuber
committed
{
int i;
bool parse_error( false );
for( i = 1; i < argc; i ++ )
{
const char* _option = argv[ i ];
if( _option[ 0 ] != '-' )
{
cerr << "Unknown option " << _option << ". Options must have prefix '--' or '-'." << endl;
parse_error = true;
continue;
}
if( strcmp( _option, "--help" ) == 0 )
{
config_description.printUsage( argv[ 0 ] );
Tomáš Oberhuber
committed
const char* option = _option + 2;
const tnlConfigEntryBase* entry;
if( ( entry = config_description.getEntry( option ) ) == NULL )
Tomáš Oberhuber
committed
{
cerr << "Unknown parameter " << _option << "." << endl;
Tomáš Oberhuber
committed
parse_error = true;
}
else
{
const tnlString& entryType = entry->getEntryType();
Tomáš Oberhuber
committed
const char* value = argv[ ++ i ];
if( ! value )
{
cerr << "Missing value for the parameter " << option << "." << endl;
return false;
}
tnlList< tnlString > parsedEntryType;
if( ! parseObjectType( entryType, parsedEntryType ) )
{
cerr << "Internal error: Uknown config entry type " << entryType << "." << endl;
return false;
}
if( parsedEntryType[ 0 ] == "tnlList" )
Tomáš Oberhuber
committed
{
tnlList< tnlString >* string_list( 0 );
tnlList< bool >* bool_list( 0 );
tnlList< int >* integer_list( 0 );
tnlList< double >* real_list( 0 );
if( parsedEntryType[ 1 ] == "tnlString" )
Tomáš Oberhuber
committed
string_list = new tnlList< tnlString >;
if( parsedEntryType[ 1 ] == "bool" )
Tomáš Oberhuber
committed
bool_list = new tnlList< bool >;
if( parsedEntryType[ 1 ] == "int" )
Tomáš Oberhuber
committed
integer_list = new tnlList< int >;
if( parsedEntryType[ 1 ] == "double" )
Tomáš Oberhuber
committed
real_list = new tnlList< double >;
while( i < argc && ( ( argv[ i ] )[ 0 ] != '-' || ( atof( argv[ i ] ) < 0.0 && ( integer_list || real_list ) ) ) )
{
const char* value = argv[ i ++ ];
if( string_list )
{
/*if( ! ( ( tnlConfigEntry< tnlList< tnlString > >* ) entry )->checkValue( tnlString( value ) ) )
{
delete string_list;
return false;
}*/
string_list -> Append( tnlString( value ) );
}
Tomáš Oberhuber
committed
if( bool_list )
{
bool bool_val;
if( ! matob( value, bool_val ) )
{
cerr << "Yes/true or no/false is required for the parameter " << option << "." << endl;
parse_error = true;
}
else bool_list -> Append( bool_val );
}
if( integer_list )
{
/*if( ! ( tnlConfigEntry< tnlList< int > >* ) entry->checkValue( atoi( value ) ) )
{
delete integer_list;
return false;
}*/
integer_list -> Append( atoi( value ) );
}
if( real_list )
{
/*if( ! ( tnlConfigEntry< tnlList< double > >* ) entry->checkValue( atof( value ) ) )
{
delete real_list;
return false;
}*/
real_list -> Append( atof( value ) );
}
Tomáš Oberhuber
committed
}
if( string_list )
{
parameters. addParameter< tnlList< tnlString > >( option, *string_list );
Tomáš Oberhuber
committed
delete string_list;
}
if( bool_list )
{
parameters. addParameter< tnlList< bool > >( option, *bool_list );
Tomáš Oberhuber
committed
delete bool_list;
}
if( integer_list )
{
parameters. addParameter< tnlList< int > >( option, *integer_list );
Tomáš Oberhuber
committed
delete integer_list;
}
if( real_list )
{
parameters. addParameter< tnlList< double > >( option, *real_list );
Tomáš Oberhuber
committed
delete real_list;
}
if( i < argc ) i --;
continue;
}
else
{
if( parsedEntryType[ 0 ] == "tnlString" )
Tomáš Oberhuber
committed
{
if( ! ( ( tnlConfigEntry< tnlString >* ) entry )->checkValue( value ) )
return false;
parameters. addParameter< tnlString >( option, value );
Tomáš Oberhuber
committed
continue;
}
if( parsedEntryType[ 0 ] == "bool" )
Tomáš Oberhuber
committed
{
bool bool_val;
if( ! matob( value, bool_val ) )
{
cerr << "Yes/true or no/false is required for the parameter " << option << "." << endl;
parse_error = true;
}
else parameters. addParameter< bool >( option, bool_val );
Tomáš Oberhuber
committed
continue;
}
if( parsedEntryType[ 0 ] == "int" )
Tomáš Oberhuber
committed
{
/*if( ! isdigit( value ) )
{
cerr << "Integer constant is required for the parameter " << option << "." << endl;
parse_error = true;
continue;
}*/
if( ! ( ( tnlConfigEntry< int >* ) entry )->checkValue( atoi( value ) ) )
return false;
parameters. addParameter< int >( option, atoi( value ) );
Tomáš Oberhuber
committed
}
if( parsedEntryType[ 0 ] == "double" )
Tomáš Oberhuber
committed
{
/*if( ! isdigit( value ) )
{
cerr << "Real constant is required for the parameter " << option << "." << endl;
parse_error = true;
continue;
}*/
if( ! ( ( tnlConfigEntry< double >* ) entry )->checkValue( atof( value ) ) )
return false;
parameters. addParameter< double >( option, atof( value ) );
Tomáš Oberhuber
committed
}
}
}
}
config_description.addMissingEntries( parameters );
if( ! config_description.checkMissingEntries( parameters, printUsage, argv[ 0 ] ) )
Tomáš Oberhuber
committed
return false;
return ! parse_error;
}