CommandOption.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: CommandOption.cpp 274 2006-10-27 14:24:35Z rickmach $"
00002 
00003 
00004 
00005 //============================================================================
00006 //
00007 //  This file is part of GPSTk, the GPS Toolkit.
00008 //
00009 //  The GPSTk is free software; you can redistribute it and/or modify
00010 //  it under the terms of the GNU Lesser General Public License as published
00011 //  by the Free Software Foundation; either version 2.1 of the License, or
00012 //  any later version.
00013 //
00014 //  The GPSTk is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //  GNU Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with GPSTk; if not, write to the Free Software Foundation,
00021 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //  
00023 //  Copyright 2004, The University of Texas at Austin
00024 //
00025 //============================================================================
00026 
00027 //============================================================================
00028 //
00029 //This software developed by Applied Research Laboratories at the University of
00030 //Texas at Austin, under contract to an agency or agencies within the U.S. 
00031 //Department of Defense. The U.S. Government retains all rights to use,
00032 //duplicate, distribute, disclose, or release this software. 
00033 //
00034 //Pursuant to DoD Directive 523024 
00035 //
00036 // DISTRIBUTION STATEMENT A: This software has been approved for public 
00037 //                           release, distribution is unlimited.
00038 //
00039 //=============================================================================
00040 
00041 
00042 
00043 
00044 
00045 
00051 #include "CommandOption.hpp"
00052 #include "StringUtils.hpp"
00053 
00054 #include <sstream>
00055 
00056 using namespace std;
00057 using namespace gpstk::StringUtils;
00058 
00059 namespace gpstk
00060 {
00061    CommandOptionVec defaultCommandOptionList;
00062 
00063       // Prints out short options with a leading '-' and long ones with '--'.
00064       // Puts a '|' between them if it has both.
00065    string CommandOption::getOptionString() const
00066    {
00067       string toReturn;
00068       if (shortOpt != 0)
00069       {
00070          toReturn += string("-") + string(1, shortOpt);
00071          if (!longOpt.empty())
00072             toReturn += string(" | --") + longOpt;
00073       }
00074       else
00075       {
00076          toReturn += string("--") + longOpt;
00077       }
00078       return toReturn;
00079    }
00080 
00081       // Prints out short options with a leading '-' and long ones with '--'.
00082       // Puts a ',' between them if it has both.
00083    string CommandOption::getFullOptionString() const
00084    {
00085       string toReturn("  ");
00086       if (shortOpt != 0)
00087       {
00088          toReturn += string("-") + string(1, shortOpt);
00089          if (!longOpt.empty())
00090          {
00091             toReturn += string(", --") + longOpt;
00092             if (optFlag == hasArgument)
00093                toReturn += "=" + getArgString();
00094          }
00095       }
00096       else
00097       {
00098          toReturn += string("    --") + longOpt;
00099          if (optFlag == hasArgument)
00100             toReturn += "=" + getArgString();
00101       }
00102       return toReturn;
00103    }
00104 
00105       // creates the struct option for getopt_long
00106    struct option CommandOption::toGetoptLongOption() const
00107    { 
00108       struct option o = {longOpt.c_str(), optFlag, NULL, 0};
00109       return o;
00110    }
00111 
00112       // makes the string for getopt
00113    std::string CommandOption::toGetoptShortOption() const
00114    { 
00115       std::string opt(1, shortOpt);
00116       if (optFlag == hasArgument) opt += ":";
00117       return opt;
00118    }
00119 
00120       // writes out the vector of values for this command option
00121    std::ostream& CommandOption::dumpValue(std::ostream& out) const
00122    {
00123       std::vector<std::string>::const_iterator itr = value.begin();
00124       while(itr != value.end()) 
00125       {
00126          out << *itr << std::endl; 
00127          itr++;
00128       }
00129       return out;
00130    }
00131 
00132       // returns a string like this:
00133       //
00134       //   -f | --foo  <arg>
00135       //        this is the description
00136       //
00137    std::string CommandOption::getDescription() const
00138    {
00139       ostringstream out;
00140          // do the option itself first
00141       out << '\t';
00142       if (shortOpt != 0)
00143       {
00144          out << '-' << shortOpt;
00145          if (!longOpt.empty())
00146             out << " | ";
00147          else
00148             out << '\t';        
00149       }
00150       if (! longOpt.empty())
00151       {
00152          out << "--" << longOpt;
00153       }
00154       if (optFlag == hasArgument)
00155       {
00156          out << " " << getArgString();
00157       }
00158          // and the description goes on a new line
00159       out << endl << prettyPrint(description, 
00160                                  "\n",
00161                                  "                  ", 
00162                                  "               ");
00163       if (maxCount != 0)
00164       {
00165          out << "\t\tUp to " << maxCount << " may be used on the command line."
00166              << endl;
00167       }
00168       return out.str();
00169    }
00170 
00171       // this checks if it expects number or string type arguments.
00172       // it returns a string describing the error, if any.
00173    string CommandOption::checkArguments()
00174    {
00175       if (required && (count == 0))
00176          return "Required option " + getOptionString() + " was not found.";
00177 
00178       return string();
00179    }
00180 
00181    string CommandOptionRest::checkArguments()
00182    {
00183       if (required && (count == 0))
00184          return "Required trailing argument was not found.";
00185 
00186       return string();
00187    }
00188 
00189    string CommandOptionWithNumberArg::checkArguments()
00190    {
00191       string errstr = CommandOption::checkArguments();
00192 
00193       if (!errstr.empty())
00194          return errstr;
00195 
00196       vector<string>::size_type vecindex;
00197       for(vecindex = 0; vecindex < value.size(); vecindex++)
00198       {
00199          if (!isDigitString(value[vecindex]))
00200          {
00201             string errstr("Argument for ");
00202             errstr += getOptionString();
00203             errstr += string(" should be a digit string.");
00204             return errstr;
00205          }
00206       }
00207 
00208       return string();
00209    }
00210 
00211    string CommandOptionWithStringArg::checkArguments()
00212    {
00213       string errstr = CommandOption::checkArguments();
00214 
00215       if (!errstr.empty())
00216          return errstr;
00217 
00218       vector<string>::size_type vecindex;
00219       for(vecindex = 0; vecindex < value.size(); vecindex++)
00220       {
00221          if (!isAlphaString(value[vecindex]))
00222          {
00223             string errstr("Argument for ");
00224             errstr += getOptionString();
00225             errstr += string(" should be an alphabetic string.");
00226             return errstr;
00227          }
00228       }
00229       return errstr;
00230    }
00231 
00232    string CommandOptionMutex::checkArguments()
00233    {
00234       if (doOneOfChecking)
00235       {
00236          string oo = CommandOptionOneOf::checkArguments();
00237          if (oo != string())
00238             return oo;
00239       }
00240 
00241          // mutex doesn't call CommandOption::checkArguments because
00242          // it uses "required" differently
00243       string errstr("Only one of the following options may be specified: ");
00244       int firstSpec = -1;
00245       bool touched = false;
00246 
00247       for (int i = 0; i < optionVec.size(); i++)
00248       {
00249          CommandOption *opt = optionVec[i];
00250 
00251          if (i)
00252             errstr += ", ";
00253          errstr += opt->getOptionString();
00254          if (opt->getCount())
00255          {
00256             if (firstSpec != -1)
00257                touched = true;
00258             else
00259                firstSpec = i;
00260          }
00261       }
00262 
00263       if (touched)
00264          return errstr;
00265 
00266       return string();
00267    }
00268 
00269    string CommandOptionOneOf::checkArguments()
00270    {
00271          // one-of doesn't call CommandOption::checkArguments because
00272          // it doesn't use "required"
00273       string errstr("One of the following options must be specified: ");
00274       bool found = false;
00275 
00276       for (int i = 0; i < optionVec.size(); i++)
00277       {
00278          if (optionVec[i]->getCount())
00279             found = true;
00280          if (i > 0)
00281             errstr += ", ";
00282          errstr += optionVec[i]->getOptionString();
00283       }
00284 
00285       if (!found)
00286          return errstr;
00287 
00288       return string();
00289    }
00290 
00291    CommandOption* CommandOptionOneOf::whichOne() const
00292    {
00293       CommandOption *rv = NULL;
00294 
00295       for (int i = 0; i < optionVec.size(); i++)
00296       {
00297          if (optionVec[i]->getCount())
00298          {
00299             rv = optionVec[i];
00300             break;
00301          }
00302       }
00303 
00304       return rv;
00305    }
00306 
00307    string CommandOptionAllOf::checkArguments()
00308    {
00309       string errstr("The following options must be used together: ");
00310       bool found = false, notFound = false;
00311 
00312       for (int i = 0; i < optionVec.size(); i++)
00313       {
00314          if (optionVec[i]->getCount())
00315             found = true;
00316          else
00317             notFound = true;
00318          if (i > 0)
00319             errstr += ", ";
00320          errstr += optionVec[i]->getOptionString();
00321       }
00322 
00323       if (found && notFound)
00324          return errstr;
00325 
00326       return string();
00327    }
00328 
00329    unsigned long CommandOptionAllOf::getCount() const
00330    {
00331       unsigned long rv = 0;
00332       for (int i = 0; i < optionVec.size(); i++)
00333       {
00334          if (optionVec[i]->getCount() == 0)
00335             return 0;
00336          rv += optionVec[i]->getCount();
00337       }
00338       return rv;
00339    }
00340 
00341    string CommandOptionDependent::checkArguments()
00342    {
00343          // dependent doesn't call CommandOption::checkArguments because
00344          // it doesn't use "required"
00345       string errstr;
00346 
00347       if (!requiree)
00348          errstr = "Null requiree (parent) for CommandOptionDependent";
00349       if (!requirer)
00350          errstr = "Null requirer (child) for CommandOptionDependent";
00351 
00352       if (requirer->getCount() && !requiree->getCount())
00353          errstr = "Option " + requirer->getOptionString() + " requires " +
00354             requiree->getOptionString();
00355 
00356       return errstr;
00357    }
00358 
00359    string CommandOptionGroupOr::getOptionString() const
00360    {
00361       string rv;
00362       if (optionVec.size() > 1)
00363          rv += "(";
00364       for (int i = 0; i < optionVec.size(); i++)
00365       {
00366          if (i) rv += ",";
00367          rv += optionVec[i]->getOptionString();
00368       }
00369       if (optionVec.size() > 1)
00370          rv += ")";
00371 
00372       return rv;
00373    }
00374 
00375    unsigned long CommandOptionGroupOr::getCount() const
00376    {
00377       unsigned long rv = 0;
00378       for (int i = 0; i < optionVec.size(); i++)
00379          rv += optionVec[i]->getCount();
00380 
00381       return rv;
00382    }
00383 
00384    unsigned long CommandOptionGroupAnd::getCount() const
00385    {
00386       unsigned long rv = 0;
00387       for (int i = 0; i < optionVec.size(); i++)
00388       {
00389          if (optionVec[i]->getCount() == 0)
00390             return 0;
00391          rv += optionVec[i]->getCount();
00392       }
00393       return rv;
00394    }
00395 
00396 } // namespace gpstk

Generated on Wed Feb 8 03:30:58 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1