command_args.cpp
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
00003 // 
00004 // g2o is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser General Public License as published
00006 // by the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // g2o 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 Lesser General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 // File: commandArgs.cpp
00018 // Copyright (c) 2009 Rainer Kümmerle <rk@raikue.net>
00019 //
00020 // This program is free software: you can redistribute it and/or modify
00021 // it under the terms of the GNU General Public License as published by
00022 // the Free Software Foundation, either version 3 of the License, or
00023 // (at your option) any later version.
00024 //
00025 // This program is distributed in the hope that it will be useful,
00026 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00027 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00028 // GNU Library General Public License for more details.
00029 //
00030 // You should have received a copy of the GNU General Public License
00031 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00032 
00033 #include "command_args.h"
00034 
00035 #include <cstdlib>
00036 #include <cstring>
00037 #include <fstream>
00038 #include <algorithm>
00039 #include "os_specific.h"
00040 using namespace std;
00041 
00042 namespace g2o {
00043 
00044 enum CommandArgumentType
00045 {
00046   CAT_DOUBLE, CAT_FLOAT, CAT_INT, CAT_STRING, CAT_BOOL
00047 };
00048 
00049 CommandArgs::CommandArgs()
00050 {
00051 }
00052 
00053 CommandArgs::~CommandArgs()
00054 {
00055 }
00056 
00057 bool CommandArgs::parseArgs(int argc, char** argv, bool exitOnError)
00058 {
00059   _progName = argv[0];
00060   int i;
00061   for (i = 1; i < argc; i++) {
00062     string name = argv[i];
00063 
00064     if (name[0] != '-') { // each param has to start with at least one dash
00065       //cerr << "Error: expecting parameter, got " << name << endl;
00066       //printHelp(cerr);
00067       //if (exitOnError)
00068         //exit(1);
00069       //return false;
00070       break;
00071     }
00072     /* first check whether it's -- and we should not continue parsing */
00073     if (name == "--") {
00074       ++i;
00075       break;
00076     }
00077 
00078     string::size_type dashPos = name.find_first_not_of('-');
00079     if (dashPos != string::npos)
00080       name = name.substr(dashPos);
00081 
00082     if (name == "help" || name == "h") {
00083       printHelp(cout);
00084       exit(0);
00085     }
00086     else {
00087       // command line argument parsing
00088       std::vector<CommandArgument>::iterator it = _args.begin();
00089       for ( ; it != _args.end(); ++it) {
00090         if (it->name == name) {
00091           if (it->type == CAT_BOOL) {
00092             if (!it->parsed) {
00093               bool* data = static_cast<bool*>(it->data);
00094               *data = !(*data);
00095             }
00096             it->parsed = true;
00097           } else {
00098             if(i >= argc-1) {
00099               fprintf(stderr, "Argument %s needs value.\n", name.c_str());
00100               printHelp(cerr);
00101               if (exitOnError)
00102                 exit(1);
00103               return false;
00104             }
00105             i++;
00106             str2arg(argv[i], *it);
00107             it->parsed = true;
00108           }
00109           break;
00110         }
00111       }
00112       if (it == _args.end()) {
00113         fprintf(stderr, "Error: Unknown Option '%s' (use -help to get list of options).\n", name.c_str());
00114         if (exitOnError)
00115           exit(1);
00116         return false;
00117       }
00118 
00119     }
00120 
00121   } // for argv[i]
00122 
00123   if ((int)_leftOvers.size() > argc - i) {
00124     cerr << "Error: program requires parameters" << endl;
00125     printHelp(cerr);
00126     if (exitOnError)
00127       exit(1);
00128     return false;
00129   }
00130   for (size_t j = 0; (i < argc && j < _leftOvers.size()); i++, j++) {
00131     string* s = static_cast<string*>(_leftOvers[j].data);
00132     *s = argv[i];
00133   }
00134 
00135   // the optional leftOvers
00136   for (size_t j = 0; (i < argc && j < _leftOversOptional.size()); i++, j++) {
00137     string* s = static_cast<string*>(_leftOversOptional[j].data);
00138     *s  = argv[i];
00139   }
00140 
00141   return true;
00142 }
00143 
00144 void CommandArgs::param(const std::string& name, bool& p, bool defValue, const std::string& desc)
00145 {
00146   CommandArgument ca;
00147   ca.name = name;
00148   ca.description = desc;
00149   ca.type = CAT_BOOL;
00150   ca.data = static_cast<void*>(&p);
00151   ca.parsed = false;
00152   p = defValue;
00153   _args.push_back(ca);
00154 }
00155 
00156 void CommandArgs::param(const std::string& name, int& p, int defValue, const std::string& desc)
00157 {
00158   CommandArgument ca;
00159   ca.name = name;
00160   ca.description = desc;
00161   ca.type = CAT_INT;
00162   ca.data = static_cast<void*>(&p);
00163   ca.parsed = false;
00164   p = defValue;
00165   _args.push_back(ca);
00166 }
00167 
00168 void CommandArgs::param(const std::string& name, float& p, float defValue, const std::string& desc)
00169 {
00170   CommandArgument ca;
00171   ca.name = name;
00172   ca.description = desc;
00173   ca.type = CAT_FLOAT;
00174   ca.data = static_cast<void*>(&p);
00175   ca.parsed = false;
00176   p = defValue;
00177   _args.push_back(ca);
00178 }
00179 
00180 void CommandArgs::param(const std::string& name, double& p, double defValue, const std::string& desc)
00181 {
00182   CommandArgument ca;
00183   ca.name = name;
00184   ca.description = desc;
00185   ca.type = CAT_DOUBLE;
00186   ca.data = static_cast<void*>(&p);
00187   ca.parsed = false;
00188   p = defValue;
00189   _args.push_back(ca);
00190 }
00191 
00192 void CommandArgs::printHelp(std::ostream& os)
00193 {
00194   if (_banner.size())
00195     os << _banner << endl;
00196   os << "Usage: " << _progName << (_args.size()>0?" [options] ":" ");
00197   if (_leftOvers.size() > 0) {
00198     for (size_t i = 0; i < _leftOvers.size(); ++i) {
00199       if (i > 0)
00200         os << " ";
00201       os << _leftOvers[i].name;
00202     }
00203   }
00204   if (_leftOversOptional.size() > 0) {
00205     if (_leftOvers.size() > 0)
00206       os << " ";
00207     for (size_t i = 0; i < _leftOversOptional.size(); ++i) {
00208       if (i > 0)
00209         os << " ";
00210       os << "[" << _leftOversOptional[i].name << "]";
00211     }
00212   }
00213   os << endl << endl;
00214   os << "General options:" << endl;
00215   os << "-------------------------------------------" << endl;
00216   os << "-help / -h           Displays this help." << endl << endl;
00217   if (_args.size() > 0) {
00218     os << "Program Options:" << endl;
00219     os << "-------------------------------------------" << endl;
00220     // build up option string to print as table
00221     vector<pair<string, string> > tableStrings;
00222     tableStrings.reserve(_args.size());
00223     size_t maxArgLen = 0;
00224     for (size_t i = 0; i < _args.size(); ++i) {
00225       if (_args[i].type != CAT_BOOL)
00226         tableStrings.push_back(make_pair(_args[i].name + " " + type2str(_args[i].type), _args[i].description));
00227       else
00228         tableStrings.push_back(make_pair(_args[i].name, _args[i].description));
00229       maxArgLen = max(maxArgLen, tableStrings.back().first.size());
00230     }
00231     sort(tableStrings.begin(), tableStrings.end(), CmpPairFirst<string,string>());
00232     maxArgLen += 3;
00233     for (size_t i = 0; i < tableStrings.size(); ++i) {
00234       os << "-" << tableStrings[i].first;
00235       for (size_t l = tableStrings[i].first.size(); l < maxArgLen; ++l)
00236         os << " ";
00237       os << tableStrings[i].second << endl;
00238     }
00239     // TODO should output description for leftOver params?
00240   }
00241 }
00242 
00243 void CommandArgs::param(const std::string& name, std::string& p, const std::string& defValue, const std::string& desc)
00244 {
00245   CommandArgument ca;
00246   ca.name = name;
00247   ca.description = desc;
00248   ca.type = CAT_STRING;
00249   ca.data = static_cast<void*>(&p);
00250   ca.parsed = false;
00251   p = defValue;
00252   _args.push_back(ca);
00253 }
00254 
00255 void CommandArgs::setBanner(const std::string& banner)
00256 {
00257   _banner = banner;
00258 }
00259 
00260 void CommandArgs::paramLeftOver(const std::string& name, std::string& p, const std::string& defValue, const std::string& desc, bool optional)
00261 {
00262   CommandArgument ca;
00263   ca.name = name;
00264   ca.description = desc;
00265   ca.type = CAT_STRING;
00266   ca.data = static_cast<void*>(&p);
00267   ca.parsed = false;
00268   ca.optional = optional;
00269   p = defValue;
00270   if (optional)
00271     _leftOversOptional.push_back(ca);
00272   else
00273     _leftOvers.push_back(ca);
00274 }
00275 
00276 const char* CommandArgs::type2str(int t) const
00277 {
00278   switch (t) {
00279     case CAT_DOUBLE:
00280       return "<double>";
00281     case CAT_FLOAT:
00282       return "<float>";
00283     case CAT_INT:
00284       return "<int>";
00285     case CAT_STRING:
00286       return "<string>";
00287     case CAT_BOOL:
00288       return "<bool>";
00289   }
00290   return "";
00291 }
00292 
00293 void CommandArgs::str2arg(const std::string& input, CommandArgument& ca) const
00294 {
00295   switch (ca.type) {
00296     case CAT_FLOAT:
00297       {
00298         float aux;
00299         bool convertStatus = convertString(input, aux);
00300         if (convertStatus) {
00301           float* data = static_cast<float*>(ca.data);
00302           *data = aux;
00303         }
00304       }
00305       break;
00306     case CAT_DOUBLE:
00307       {
00308         double aux;
00309         bool convertStatus = convertString(input, aux);
00310         if (convertStatus) {
00311           double* data = static_cast<double*>(ca.data);
00312           *data = aux;
00313         }
00314       }
00315       break;
00316     case CAT_INT:
00317       {
00318         int aux;
00319         bool convertStatus = convertString(input, aux);
00320         if (convertStatus) {
00321           int* data = static_cast<int*>(ca.data);
00322           *data = aux;
00323         }
00324       }
00325       break;
00326     case CAT_BOOL:
00327       {
00328         bool aux;
00329         bool convertStatus = convertString(input, aux);
00330         if (convertStatus) {
00331           bool* data = static_cast<bool*>(ca.data);
00332           *data = aux;
00333         }
00334       }
00335       break;
00336     case CAT_STRING:
00337       {
00338         string* data = static_cast<string*>(ca.data);
00339         *data = input;
00340       }
00341       break;
00342   }
00343 }
00344 
00345 std::string CommandArgs::arg2str(const CommandArgument& ca) const
00346 {
00347   switch (ca.type) {
00348     case CAT_FLOAT:
00349       {
00350         float* data = static_cast<float*>(ca.data);
00351         stringstream auxStream;
00352         auxStream << *data;
00353         return auxStream.str();
00354       }
00355       break;
00356     case CAT_DOUBLE:
00357       {
00358         double* data = static_cast<double*>(ca.data);
00359         stringstream auxStream;
00360         auxStream << *data;
00361         return auxStream.str();
00362       }
00363       break;
00364     case CAT_INT:
00365       {
00366         int* data = static_cast<int*>(ca.data);
00367         stringstream auxStream;
00368         auxStream << *data;
00369         return auxStream.str();
00370       }
00371       break;
00372     case CAT_BOOL:
00373       {
00374         bool* data = static_cast<bool*>(ca.data);
00375         stringstream auxStream;
00376         auxStream << *data;
00377         return auxStream.str();
00378       }
00379       break;
00380     case CAT_STRING:
00381       {
00382         string* data = static_cast<string*>(ca.data);
00383         return *data;
00384       }
00385       break;
00386   }
00387   return "";
00388 }
00389 
00390 std::string CommandArgs::trim(const std::string& s) const
00391 {
00392   if(s.length() == 0)
00393     return s;
00394   string::size_type b = s.find_first_not_of(" \t\n");
00395   string::size_type e = s.find_last_not_of(" \t\n");
00396   if(b == string::npos)
00397     return "";
00398   return std::string(s, b, e - b + 1);
00399 }
00400 
00401 }


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:30:57