void ArgMap::parseArgv( int argc, char* argv[], bool strict ) { string option, value; // -c prog.conf --config=prog.conf -- progdir for( int pos = 1; pos < argc; pos++ ) // skip program name { option = string( argv[pos] ); switch( this->getOptionType( option ) ) { case ArgMap::Item: this->parseItem( option, strict ); break; case ArgMap::Delimiter: do { this->parseItem( string( argv[++pos] ), strict ); } while( pos < argc ); break; case ArgMap::Short: option = string( argv[pos]+1, 1 ); value = "yes"; if( m_arg[m_short[option]].req ) { if( pos+1 >= argc ) { throw ArgException( "Option '-" + option + "' requires a value" ); } else { value = string( argv[++pos] ); } } this->parseShortOption( option, value, strict ); break; case ArgMap::Long: this->parseLongOption( string( argv[pos] + 2 ), strict ); break; default: throw ArgException( "Invalid option type for '" + option + "'" ); } } }
void ArgMap::parseLongOption( const string& keyvalue, bool strict ) { string::size_type pos, begin, end; string name; if( ( pos = keyvalue.find( "=" ) ) == string::npos ) { parseItem( keyvalue, strict ); return; } begin = keyvalue.find_first_not_of( " \t", 0 ); end = keyvalue.find_last_not_of( " \t", pos - 1 ); name = keyvalue.substr( begin, end - begin + 1 ); if( strict && !m_long.count( name ) ) { throw ArgException( "ArgMap: Undefined parameter '" + name + "'" ); } begin = keyvalue.find_first_not_of( " \t", pos + 1 ); end = keyvalue.find_last_not_of( " \t", string::npos ); keyvalue[begin] == '"' ? begin++ : begin; keyvalue[end] == '"' ? end-- : end; if( begin != string::npos ) { m_arg[m_long[name]].value = keyvalue.substr( begin, end - begin + 1 ); } }
long ArgMap::asLong( const string& arg ) { char* end; long num; if( !m_long.count( arg ) ) { throw ArgException( "ArgMap: Undefined parameter '" + arg + "'" ); } num = strtol( m_arg[m_long[arg]].value.c_str(), &end, 10 ); if( *end != '\0' ) { throw ArgException( "ArgMap: Value of '" + arg + "' is not an integer" ); } return num; }
bool ArgMap::mustDo( const string& arg ) { if( !m_long.count( arg ) ) { throw ArgException( "ArgMap: Undefined parameter '" + arg + "'" ); } return ( m_arg[m_long[arg]].value == "yes" ); }
void ArgMap::parseShortOption( const string& name, const string& value, bool strict ) { if( strict && !m_short.count( name ) ) { throw ArgException( "ArgMap: Undefined parameter '" + name + "'" ); } m_arg[m_short[name]].value = value; }
const string& ArgMap::asString( const string& arg ) { if( !m_long.count( arg ) ) { throw ArgException( "ArgMap: Undefined parameter '" + arg + "'" ); } return m_arg[m_long[arg]].value; }
double ArgMap::asDouble( const string& arg ) { char * end; double num; if( !m_long.count( arg ) ) { throw ArgException( "ArgMap: Undefined parameter '" + arg + "'" ); } num = strtod( m_arg[m_long[arg]].value.c_str(), &end ); if( *end != '\0' ) { throw ArgException( "ArgMap: Value of '" + arg + "' is not a float" ); } return num; }
inline void Args::HandleBuild( ostream& os ) const { string build = "--build"; char** arg = std::find( argv_, argv_+argc_, build ); const bool foundBuild = ( arg != argv_+argc_ ); if( foundBuild ) { if( mpi::WorldRank() == 0 ) { PrintVersion(); PrintConfig(); PrintCCompilerInfo(); PrintCxxCompilerInfo(); } throw ArgException(); } }
void ArgMap::parseFile( const string& filename, bool strict ) { string::size_type pos; string line, statement; std::ifstream file( filename.c_str() ); if( !file ) { throw ArgException( "ArgMap: Can't open file " + filename ); } while( getline( file, line ) ) { if( ( pos = line.find( '#' ) ) != string::npos ) { line.erase( pos, string::npos ); } if( line.find_first_not_of( " \t" ) == string::npos ) { statement = ""; continue; } if( ( pos = line.rfind( '\\' ) ) == string::npos ) { this->parseLongOption( statement + line, strict ); statement = ""; continue; } line.erase( pos - 1, string::npos ); statement += line; } file.close(); }