Google

Main Page   Namespace List   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

LeoArg.cpp

Go to the documentation of this file.
00001 #include "LeoArg.hh"
00002 #include "StringUtils.hh"
00003 
00004 using std::string;
00005 /*
00006 bool isnum( const std::string &s );
00007 void toupper( std::string &s );
00008 std::strstream& operator >> ( std::strstream& in, bool& w );
00009 */
00010 
00011 LeoArg::Option::Option( string long_option, string short_option )
00012   : long_option( long_option ), 
00013     short_option( short_option )
00014 {
00015   bool_value = false;
00016   int_num = 0;
00017   double_num = 0.0;
00018   str = "";
00019   flag = false;
00020 }
00021 
00022 LeoArg::LeoArg( Setting& setting )
00023   : setting( setting )
00024 {
00025   correct_setting();
00026    
00027   for( OptionListIt it = setting.option_list.begin();
00028        it != setting.option_list.end(); it++ )
00029     parse_option( *it );
00030 }
00031 
00032 LeoArg::LeoArg( int argc, char **argv, string long_option_switch, string short_option_switch )
00033   :  setting( argc, argv, long_option_switch, short_option_switch )
00034 {
00035   setting.short_option_string( false );
00036 
00037   correct_setting();
00038 
00039   for( OptionListIt it = setting.option_list.begin();
00040        it != setting.option_list.end(); it++ )
00041     parse_option( *it );
00042 }
00043 
00044 bool LeoArg::parse_option( Option& option ) const
00045 {
00046   bool found = false;
00047   int i;
00048   for( i=1; i < setting.argc; i++ )
00049     {
00050       string av = setting.argv[i];
00051       if( av == setting.long_option_switch + option.long_option ||
00052           av == setting.short_option_switch + option.short_option )
00053         {
00054           found = true;
00055           break;
00056         }
00057     }
00058 
00059   if( !found )
00060     {
00061       if( setting.sos )
00062         {
00063           int s;
00064           if( s = has_sos() )
00065             {
00066               if( is_in_sos( option ) )
00067                 found = true;
00068             }
00069         }
00070     }
00071 
00072   if( found )
00073     {
00074       // find the next option
00075       int num = 0;
00076       int j;
00077       for( j = i + 1; j < setting.argc; j++ )
00078         {
00079           string av = setting.argv[j];
00080           if( av.find( setting.long_option_switch ) == 0 ||
00081               av.find( setting.short_option_switch ) == 0 )
00082             break;
00083         }
00084 
00085       num = j - i;
00086 
00087       option.flag = true; // the option was found
00088 
00089       if( num > 1 )
00090         {
00091           option.bool_value = StringUtils::s2x<bool>(setting.argv[i+1]);
00092           option.int_num = StringUtils::s2x<int>(setting.argv[i+1]);
00093           option.double_num = StringUtils::s2x<double>(setting.argv[i+1]);
00094           option.str = setting.argv[i+1];
00095           
00096           for( int j = i+1; j < i + num; j++ )
00097             option.arglist.push_back( setting.argv[j] );
00098         }
00099       return true;
00100     }
00101    
00102   return false;
00103 }
00104 
00105 void LeoArg::correct_option( Option& option ) const
00106 {
00107   StringUtils::strip( option.long_option );
00108   StringUtils::strip( option.short_option );
00109 
00110   if( option.long_option.empty() )
00111     option.long_option = option.short_option;
00112 
00113   if( option.short_option.empty() )
00114     option.short_option = option.long_option;
00115 
00116   if( option.short_option.empty() && option.long_option.empty() )
00117     throw InvalidOption( option, "(long_option == \"\") && (short_option == \"\")" );
00118 }
00119 
00120 void LeoArg::correct_setting()
00121 {
00122   if( setting.argc <= 0 ) 
00123     throw InvalidSetting( "argc <= 0" );
00124 
00125   StringUtils::strip( setting.long_option_switch );
00126   StringUtils::strip( setting.short_option_switch );
00127 
00128   if( setting.long_option_switch.empty() )
00129     setting.long_option_switch = setting.short_option_switch;
00130 
00131   if( setting.short_option_switch.empty() )
00132     setting.short_option_switch = setting.long_option_switch;
00133 
00134   if( setting.short_option_switch.empty() && setting.long_option_switch.empty() )
00135     throw InvalidSetting( "short_option_switch == \"\" && long_option_switch == \"\"" );
00136 
00137   for( OptionListIt it = setting.option_list.begin(); 
00138        it != setting.option_list.end(); it++ )
00139     correct_option( *it );
00140 }
00141 
00142 bool LeoArg::get_option( Option& option )
00143 {
00144   correct_option( option );
00145 
00146   if( find_option( option ) )
00147     return true;
00148 
00149   setting.add( option );
00150 
00151   return parse_option( option );
00152 }
00153 
00154 bool LeoArg::find_option( Option& option ) const
00155 {
00156   for( OptionListIt it = setting.option_list.begin();
00157        it != setting.option_list.end(); it++ )
00158     {
00159       if( it->long_option == option.long_option )
00160         {
00161           option = *it;
00162           return true;
00163         }
00164     }
00165   return false;
00166 }
00167 
00168 
00169 bool LeoArg::get_first( string& ret_value ) const
00170 {
00171   if(  has_parameters() )
00172     {
00173       string av = setting.argv[1];
00174       if( av.find( setting.long_option_switch ) == 0 ||
00175           av.find( setting.short_option_switch ) == 0 )
00176         return false;
00177 
00178       ret_value = av;
00179       return true;
00180     }
00181   return false;
00182 }
00183 
00184 
00185 bool LeoArg::get_first( ArgList& arglist ) const
00186 {
00187   if(  has_parameters() )
00188     {
00189       for( int i = 1; i < setting.argc; i++ )
00190         {
00191           string av = setting.argv[i];
00192           if( av.find( setting.long_option_switch ) == 0 ||
00193               av.find( setting.short_option_switch ) == 0 )
00194             break;
00195           arglist.push_back( av );
00196         }
00197 
00198       return true;
00199     }
00200   return false;
00201 }
00202 
00203 
00204 bool LeoArg::get_last( string& ret_value ) const
00205 {
00206   if(  has_parameters() )
00207     {
00208       string av = setting.argv[setting.argc - 1];
00209       if( av.find( setting.long_option_switch ) == 0 ||
00210           av.find( setting.short_option_switch ) == 0 )
00211         return false;
00212 
00213       ret_value = av;
00214       return true;
00215     }
00216   return false;
00217 }
00218 
00219 
00220 bool LeoArg::get_last( ArgList& arglist ) const
00221 {
00222   if(  has_parameters() )
00223     {
00224       for( int i = setting.argc - 1; i > 1; i-- )
00225         {
00226           string av = setting.argv[i];
00227           if( av.find( setting.long_option_switch ) == 0 ||
00228               av.find( setting.short_option_switch ) == 0 )
00229             break;
00230           arglist.push_back( av );
00231         }
00232 
00233       return true;
00234     }
00235   return false;
00236 }
00237 
00238 bool LeoArg::is_in_sos( const Option& option ) const
00239 {
00240   if( option.short_option.size() != 1 )
00241     return false; // only one character options are allowed
00242 
00243   int i;
00244 
00245   if( i = has_sos() )
00246     {
00247       string arg = setting.argv[i];
00248       arg = arg.substr( 1 ); // eleminate option symbol
00249 
00250       if( arg.find( option.short_option ) != string::npos )
00251         return true;
00252     }
00253 
00254   return false;
00255 }
00256 
00259 int LeoArg::has_sos() const
00260 {
00261   if( !has_parameters() )
00262     return 0;
00263 
00264   for( int i = 1; i < setting.argc; i++ )
00265     {
00266       string av = setting.argv[i];
00267       if( av.find( setting.short_option_switch ) == 0 && 
00268           av.find( setting.long_option_switch ) != 0 )
00269         {
00270           Option o( "#__LEOARG__#", av.substr( 1 ) );
00271           if( !find_option( o ) )
00272             return i;
00273         }
00274     }
00275   return 0;
00276 }
00277 
00278 extern "C" {
00279   char leoarg() { return 1; }
00280   char leoarg_version_2_2() { return 1; }
00281 }

LeoArg (C) under the terms of the GPL by King Leo (Martin Oberzalek)
Documentation created by Doxygen 1.2.2