FastJet 3.0.4
CmdLine.cc
00001 ///////////////////////////////////////////////////////////////////////////////
00002 // File: CmdLine.cc                                                          //
00003 // Part of the CmdLine library                                               //
00004 //                                                                           //
00005 // Copyright (c) 2007 Gavin Salam                                            //
00006 //                                                                           //
00007 // This program is free software; you can redistribute it and/or modify      //
00008 // it under the terms of the GNU General Public License as published by      //
00009 // the Free Software Foundation; either version 2 of the License, or         //
00010 // (at your option) any later version.                                       //
00011 //                                                                           //
00012 // This program is distributed in the hope that it will be useful,           //
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of            //
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             //
00015 // GNU General Public License for more details.                              //
00016 //                                                                           //
00017 // You should have received a copy of the GNU General Public License         //
00018 // along with this program; if not, write to the Free Software               //
00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
00020 //                                                                           //
00021 // $Revision:: 139                                                          $//
00022 // $Date:: 2007-01-23 16:09:23 +0100 (Tue, 23 Jan 2007)                     $//
00023 ///////////////////////////////////////////////////////////////////////////////
00024 
00025 
00026 
00027 #include "CmdLine.hh"
00028 #include<string>
00029 #include<sstream>
00030 #include<iostream> // testing
00031 #include<vector>
00032 #include<cstddef> // for size_t
00033 #include<cstdlib> // for exit
00034 using namespace std;
00035 
00036 // initialise the various structures that we shall
00037 // use to access the command-line options;
00038 //
00039 // If an option appears several times, it is its LAST value
00040 // that will be used in searching for option values (opposite of f90)
00041 CmdLine::CmdLine (const int argc, char** argv) {
00042   __arguments.resize(argc);
00043   for(int iarg = 0; iarg < argc; iarg++){
00044     __arguments[iarg] = argv[iarg];
00045   }
00046   this->init();
00047 }
00048 
00049 /// constructor from a vector of strings, one argument per string
00050 CmdLine::CmdLine (const vector<string> & args) {
00051   __arguments = args;
00052   this->init();
00053 }
00054 
00055 //----------------------------------------------------------------------
00056 void CmdLine::init (){
00057   __command_line = "";
00058   for(size_t iarg = 0; iarg < __arguments.size(); iarg++){
00059     __command_line += __arguments[iarg];
00060     __command_line += " ";
00061   }
00062   
00063   // group things into options
00064   bool next_may_be_val = false;
00065   string currentopt;
00066   for(size_t iarg = 1; iarg < __arguments.size(); iarg++){
00067     // if expecting an option value, then take it (even if
00068     // it is actually next option...)
00069     if (next_may_be_val) {__options[currentopt] = iarg;}
00070     // now see if it might be an option itself
00071     string arg = __arguments[iarg];
00072     bool thisisopt = (arg.compare(0,1,"-") == 0);
00073     if (thisisopt) {
00074       // set option to a standard undefined value and say that 
00075       // we expect (possibly) a value on next round
00076       currentopt = arg;
00077       __options[currentopt] = -1;
00078       __options_used[currentopt] = false;
00079       next_may_be_val = true;}
00080     else {
00081       // otherwise throw away the argument for now...
00082       next_may_be_val = false;
00083       currentopt = "";
00084     }
00085   }
00086 }
00087 
00088 // indicates whether an option is present
00089 bool CmdLine::present(const string & opt) const {
00090   bool result = (__options.find(opt) != __options.end());
00091   if (result) __options_used[opt] = true;
00092   return result;
00093 }
00094 
00095 // indicates whether an option is present and has a value associated
00096 bool CmdLine::present_and_set(const string & opt) const {
00097   bool result = present(opt) && __options[opt] > 0;
00098   return result;
00099 }
00100 
00101 
00102 // return the string value corresponding to the specified option
00103 string CmdLine::string_val(const string & opt) const {
00104   if (!this->present_and_set(opt)) {
00105     cerr << "Error: Option "<<opt
00106          <<" is needed but is not present_and_set"<<endl;
00107     exit(-1);
00108   }
00109   string arg = __arguments[__options[opt]];
00110   // this may itself look like an option -- if that is the case
00111   // declare the option to have been used
00112   if (arg.compare(0,1,"-") == 0) {__options_used[arg] = true;}
00113   return arg;
00114 }
00115 
00116 // as above, but if opt is not present_and_set, return default
00117 string CmdLine::string_val(const string & opt, const string & defval) const {
00118   if (this->present_and_set(opt)) {return string_val(opt);} 
00119   else {return defval;}
00120 }
00121 
00122 // Return the integer value corresponding to the specified option;
00123 // Not too sure what happens if option is present_and_set but does not
00124 // have string value...
00125 int CmdLine::int_val(const string & opt) const {
00126   int result;
00127   string optstring = string_val(opt);
00128   istringstream optstream(optstring);
00129   optstream >> result;
00130   if (optstream.fail()) {
00131     cerr << "Error: could not convert option ("<<opt<<") value ("
00132          <<optstring<<") to int"<<endl; 
00133     exit(-1);}
00134   return result;
00135 }
00136 
00137 // as above, but if opt is not present_and_set, return default
00138 int CmdLine::int_val(const string & opt, const int & defval) const {
00139   if (this->present_and_set(opt)) {return int_val(opt);} 
00140   else {return defval;}
00141 }
00142 
00143 
00144 // Return the integer value corresponding to the specified option;
00145 // Not too sure what happens if option is present_and_set but does not
00146 // have string value...
00147 double CmdLine::double_val(const string & opt) const {
00148   double result;
00149   string optstring = string_val(opt);
00150   istringstream optstream(optstring);
00151   optstream >> result;
00152   if (optstream.fail()) {
00153     cerr << "Error: could not convert option ("<<opt<<") value ("
00154          <<optstring<<") to double"<<endl; 
00155     exit(-1);}
00156   return result;
00157 }
00158 
00159 // as above, but if opt is not present_and_set, return default
00160 double CmdLine::double_val(const string & opt, const double & defval) const {
00161   if (this->present_and_set(opt)) {return double_val(opt);} 
00162   else {return defval;}
00163 }
00164 
00165 
00166 // return the full command line including the command itself
00167 string CmdLine::command_line() const {
00168   return __command_line;
00169 }
00170 
00171 
00172 // return true if all options have been asked for at some point or other
00173 bool CmdLine::all_options_used() const {
00174   bool result = true;
00175   for(map<string,bool>::const_iterator opt = __options_used.begin();
00176       opt != __options_used.end(); opt++) {
00177     bool this_one = opt->second;
00178     if (! this_one) {cerr << "Option "<<opt->first<<" unused/unrecognized"<<endl;}
00179     result = result && this_one;
00180   }
00181   return result;
00182 }
00183 
00184 
00185 /// report failure of conversion
00186 void CmdLine::_report_conversion_failure(const string & opt, 
00187                                          const string & optstring) const {
00188   cerr << "Error: could not convert option ("<<opt<<") value ("
00189        <<optstring<<") to requested type"<<endl; 
00190   exit(-1);
00191 }
00192 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends