/*************************************************************************** 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" #include <core/tnlObject.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 tnlString& name, const tnlString& value ) { return parameters. Append( new tnlParameter< tnlString >( name, ::getType< tnlString >().getString(), tnlString( value ) ) ); } bool tnlParameterContainer:: setParameter( const tnlString& name, const tnlString& value ) { int i; for( i = 0; i < parameters. getSize(); i ++ ) { if( parameters[ i ] -> name == name ) { if( parameters[ i ] -> type == ::getType< tnlString >() ) { ( ( tnlParameter< tnlString > * ) parameters[ i ] )->value = value; return true; } else { cerr << "Parameter " << name << " already exists with different type " << parameters[ i ] -> type << " not " << ::getType< tnlString>() << endl; abort(); return false; } } } return addParameter( name, value ); }; bool tnlParameterContainer:: checkParameter( const tnlString& 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, bool printUsage ) { 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 ] ); return true; } const char* option = _option + 2; const tnlConfigEntryBase* entry; if( ( entry = config_description.getEntry( option ) ) == NULL ) { cerr << "Unknown parameter " << _option << "." << endl; parse_error = true; } else { const tnlString& entryType = entry->getEntryType(); 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" ) { tnlList< tnlString >* string_list( 0 ); tnlList< bool >* bool_list( 0 ); tnlList< int >* integer_list( 0 ); tnlList< double >* real_list( 0 ); if( parsedEntryType[ 1 ] == "tnlString" ) string_list = new tnlList< tnlString >; if( parsedEntryType[ 1 ] == "bool" ) bool_list = new tnlList< bool >; if( parsedEntryType[ 1 ] == "int" ) integer_list = new tnlList< int >; if( parsedEntryType[ 1 ] == "double" ) 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 ) ); } 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 ) ); } } 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( parsedEntryType[ 0 ] == "tnlString" ) { if( ! ( ( tnlConfigEntry< tnlString >* ) entry )->checkValue( value ) ) return false; parameters. addParameter< tnlString >( option, value ); continue; } if( parsedEntryType[ 0 ] == "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( parsedEntryType[ 0 ] == "int" ) { /*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 ) ); } if( parsedEntryType[ 0 ] == "double" ) { /*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 ) ); } } } } config_description.addMissingEntries( parameters ); if( ! config_description.checkMissingEntries( parameters, printUsage, argv[ 0 ] ) ) return false; return ! parse_error; }