ISIS Core Library 0.7.2 (api 3.0.0)
|
00001 /* 00002 Copyright (C) 2010 reimer@cbs.mpg.de 00003 00004 This program is free software: you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation, either version 3 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program. If !, see <http://www.gnu.org/licenses/>. 00016 00017 */ 00018 00019 #include "progparameter.hpp" 00020 #include <boost/foreach.hpp> 00021 00022 namespace isis 00023 { 00024 namespace util 00025 { 00026 00027 ProgParameter::ProgParameter(): m_hidden( false ), m_set( false ) 00028 { 00029 needed() = true; 00030 } 00031 00032 bool ProgParameter::isHidden() const 00033 { 00034 return m_hidden; 00035 } 00036 bool &ProgParameter::hidden() 00037 { 00038 return m_hidden; 00039 } 00040 00041 bool ProgParameter::parse( const Value<std::string> &props ) 00042 { 00043 ValueBase &me = **this; 00044 bool ret = false; 00045 00046 if ( ( ( std::string )props ).empty() ) { 00047 if ( me.is<bool>() ) { 00048 me.castTo<bool>() = true; 00049 ret = true; 00050 } 00051 } else { 00052 ret = ValueBase::convert( props, me ); 00053 } 00054 00055 LOG_IF( ret, Debug, info ) << "Parsed " << MSubject( props.toString() ) << " as " << me.toString( true ); 00056 00057 if( ret )m_set = true; 00058 00059 return ret; 00060 } 00061 bool ProgParameter::parse_list( const isis::util::Value< slist >& props_list ) 00062 { 00063 ValueBase &me = **this; 00064 bool ret = false; 00065 const util::slist &theList = props_list.castTo<util::slist>(); 00066 00067 if ( theList.empty() ) { 00068 //there is nothing like a bool-list (yet) 00069 } else { 00070 ret = ValueBase::convert( props_list, me ); 00071 } 00072 00073 LOG_IF( ret, Debug, info ) 00074 << "Parsed parameter list " << MSubject( util::listToString( theList.begin(), theList.end(), " ", "", "" ) ) << " as " << me.toString( true ); 00075 00076 if( ret )m_set = true; 00077 00078 return ret; 00079 } 00080 00081 00082 const std::string &ProgParameter::description()const 00083 { 00084 return m_description; 00085 } 00086 void ProgParameter::setDescription( const std::string &desc ) 00087 { 00088 m_description = desc; 00089 } 00090 bool ProgParameter::isSet() const 00091 { 00092 return m_set; 00093 } 00094 00095 00096 ParameterMap::ParameterMap(): parsed( false ) {} 00097 00098 bool ParameterMap::parse( int argc, char **argv ) 00099 { 00100 parsed = true; 00101 std::string pName; 00102 00103 for ( int i = 1; i < argc; ) { // scan through the command line, to find next parameter 00104 if ( argv[i][0] == '-' ) { //seems like we found a new parameter here 00105 pName = argv[i]; 00106 pName.erase( 0, pName.find_first_not_of( '-' ) ); 00107 } else { 00108 LOG( Runtime, error ) << "Ignoring unexpected non-parameter " << MSubject( argv[i] ); 00109 } 00110 00111 i++; 00112 00113 if( !pName.empty() ) { // if we got a parameter before 00114 const int start = i; 00115 00116 while( i < argc && argv[i][0] != '-' ) { //collect its properties, while there are some .. 00117 i++; 00118 } 00119 00120 std::list<std::string> matchingStrings; 00121 BOOST_FOREACH( ParameterMap::const_reference parameterRef, *this ) { 00122 if( parameterRef.first.find( pName ) == 0 ) { 00123 if( parameterRef.first.length() == pName.length() ) { //if its an exact match 00124 matchingStrings = std::list<std::string>( 1, pName ); //use that 00125 break;// and stop searching for partial matches 00126 } else 00127 matchingStrings.push_back( parameterRef.first ); 00128 } 00129 } 00130 00131 if( matchingStrings.size() > 1 ) { 00132 std::stringstream matchingStringStream; 00133 BOOST_FOREACH( std::list<std::string>::const_reference stringRef, matchingStrings ) { 00134 matchingStringStream << stringRef << " "; 00135 } 00136 LOG( Runtime, warning ) 00137 << "The parameter \"" << pName << "\" is ambiguous. The parameters \"" 00138 << matchingStringStream.str().erase( matchingStringStream.str().size() - 1, 1 ) 00139 << "\" are possible. Ignoring this parameter!"; 00140 } else if ( !matchingStrings.size() ) { 00141 LOG( Runtime, warning ) << "Ignoring unknown parameter " << MSubject( std::string( "-" ) + pName + " " + listToString( argv + start, argv + i, " ", "", "" ) ); 00142 } else { 00143 if( at( matchingStrings.front() ).is<util::slist>() && 00144 at( matchingStrings.front() ).parse_list( util::slist( argv + start, argv + i ) ) 00145 ) { //dont do tokenizing if the target is an slist (is already done by the shell) 00146 at( matchingStrings.front() ).needed() = false; //remove needed flag, because the value is set (aka "not needed anymore") 00147 } else if ( at( matchingStrings.front() ).parse( listToString( argv + start, argv + i, ",", "", "" ) ) ) { // parse the collected properties 00148 at( matchingStrings.front() ).needed() = false; //remove needed flag, because the value is set (aka "not needed anymore") 00149 } else { 00150 LOG( Runtime, error ) 00151 << "Failed to parse the parameter " << MSubject( std::string( "-" ) + matchingStrings.front() ) << ": " 00152 << ( start == i ? "nothing" : listToString( argv + start, argv + i, " ", "\"", "\"" ) ) 00153 << " was given, but a " << at( matchingStrings.front() ).getTypeName() << " was expected."; 00154 parsed = false; 00155 } 00156 00157 } 00158 } 00159 } 00160 00161 return parsed ; 00162 } 00163 bool ParameterMap::isComplete()const 00164 { 00165 LOG_IF( ! parsed, Debug, error ) << "You did not run parse() yet. This is very likely an error"; 00166 return std::find_if( begin(), end(), neededP() ) == end(); 00167 } 00168 00169 const ProgParameter ParameterMap::operator[] ( const std::string key ) const 00170 { 00171 std::map<std::string, ProgParameter>::const_iterator at = find( key ); 00172 00173 if( at != end() ) 00174 return at->second; 00175 else { 00176 LOG( Debug, error ) << "The requested parameter " << util::MSubject( key ) << " does not exist"; 00177 return ProgParameter(); 00178 } 00179 } 00180 ProgParameter &ParameterMap::operator[] ( const std::string key ) {return std::map<std::string, ProgParameter>::operator[]( key );} 00181 00182 ProgParameter::operator boost::scoped_ptr<ValueBase>::unspecified_bool_type()const 00183 { 00184 boost::scoped_ptr<ValueBase> dummy; 00185 00186 if( ( *this ).castTo<bool>() )dummy.reset( new Value<int16_t> ); 00187 00188 return dummy; 00189 } 00190 00191 } 00192 }