/*************************************************************************** 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> #include "tnlParameterContainer.h" 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() { } //-------------------------------------------------------------------------- bool tnlParameterContainer :: AddParameter( const char* name, const char* value ) { return parameters. Append( new tnlParameter< tnlString >( name, GetParameterType( tnlString() ). getString(), tnlString( value ) ) ); } //-------------------------------------------------------------------------- bool tnlParameterContainer :: SetParameter( const char* name, const char* value ) { int i; for( i = 0; i < parameters. getSize(); i ++ ) { if( parameters[ i ] -> name == name ) { if( parameters[ i ] -> type == getParameterType< tnlString >() ) { ( ( tnlParameter< tnlString > * ) parameters[ i ] ) -> value. setString( value ); return true; } else { cerr << "Parameter " << name << " already exists with different type " << parameters[ i ] -> type << " not " << GetParameterType( value ) << endl; abort(); return false; } } } return AddParameter( name, value ); }; //-------------------------------------------------------------------------- bool tnlParameterContainer :: CheckParameter( const char* name ) const { 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() { parameters. DeepEraseAll(); } //-------------------------------------------------------------------------- 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(), val ); } if( param_type == "bool" ) { bool val; :: MPIBcast( val, 1, root, mpi_comm ); AddParameter< bool >( param_name. getString(), val ); } if( param_type == "int" ) { int val; :: MPIBcast( val, 1, root, mpi_comm ); AddParameter< int >( param_name. getString(), val ); } if( param_type == "double" ) { double val; :: MPIBcast( val, 1, root, mpi_comm ); AddParameter< double >( param_name. getString(), val ); } } } #endif } //-------------------------------------------------------------------------- bool ParseCommandLine( int argc, char* argv[], const tnlConfigDescription& config_description, tnlParameterContainer& parameters ) { 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; } const char* option = _option + 2; const tnlConfigEntryType* entry_type; if( ! ( entry_type = config_description. GetEntryType( option ) ) ) { cerr << "Unknown parameter " << option << "." << endl; parse_error = true; } else { const char* value = argv[ ++ i ]; if( ! value ) { cerr << "Missing value for the parameter " << option << "." << endl; return false; } const tnlString& basic_type_name = entry_type -> basic_type; if( entry_type -> list_entry ) { tnlList< tnlString >* string_list( 0 ); tnlList< bool >* bool_list( 0 ); tnlList< int >* integer_list( 0 ); tnlList< double >* real_list( 0 ); if( basic_type_name == "string" ) string_list = new tnlList< tnlString >; if( basic_type_name == "bool" ) bool_list = new tnlList< bool >; if( basic_type_name == "integer" ) integer_list = new tnlList< int >; if( basic_type_name == "real" ) 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 ) string_list -> Append( tnlString( value ) ); 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 ) integer_list -> Append( atoi( value ) ); if( real_list ) real_list -> Append( atof( value ) ); } if( string_list ) { parameters. AddParameter< tnlList< tnlString > >( option, *string_list ); delete string_list; } if( bool_list ) { parameters. AddParameter< tnlList< bool > >( option, *bool_list ); delete bool_list; } if( integer_list ) { parameters. AddParameter< tnlList< int > >( option, *integer_list ); delete integer_list; } if( real_list ) { parameters. AddParameter< tnlList< double > >( option, *real_list ); delete real_list; } if( i < argc ) i --; continue; } else { if( basic_type_name == "string" ) { parameters. AddParameter< tnlString >( option, value ); continue; } if( basic_type_name == "bool" ) { 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 ); continue; } if( basic_type_name == "integer" ) { /*if( ! isdigit( value ) ) { cerr << "Integer constant is required for the parameter " << option << "." << endl; parse_error = true; continue; }*/ parameters. AddParameter< int >( option, atoi( value ) ); } if( basic_type_name == "real" ) { /*if( ! isdigit( value ) ) { cerr << "Real constant is required for the parameter " << option << "." << endl; parse_error = true; continue; }*/ parameters. AddParameter< double >( option, atof( value ) ); } } } } config_description. AddMissingEntries( parameters ); if( ! config_description. CheckMissingEntries( parameters ) ) return false; return ! parse_error; }