ngetopt.hpp

Go to the documentation of this file.
00001 // LICENSE: (Please see the file COPYING for details)
00002 //
00003 // NUS - Nemesis Utilities System: A C++ application development framework 
00004 // Copyright (C) 2006, 2008 Otavio Rodolfo Piske
00005 //
00006 //  This file is part of NUS
00007 //
00008 //  This library is free software; you can redistribute it and/or
00009 //  modify it under the terms of the GNU Lesser General Public
00010 //  License as published by the Free Software Foundation version 2.1
00011 //  of the License.
00012 //
00013 //  This library is distributed in the hope that it will be useful,
00014 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 //  Lesser General Public License for more details.
00017 //
00018 //  You should have received a copy of the GNU Lesser General Public
00019 //  License along with this library; if not, write to the Free Software
00020 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021 //
00022 #ifndef NGETOPT_HPP
00023 #define NGETOPT_HPP
00024 
00036 template <typename HandlerType>
00037 class NGetOpt: public NObject {
00038       public:
00039             
00043             enum Style {
00044                   GNU_STYLE,        
00045                   BSD_STYLE,        
00046                   WINDOWS_STYLE,    
00047             };
00048             
00052             typedef NList< NOpt<HandlerType> > NOptList;
00053       
00054       
00065             NGetOpt(int argc, char **argv, HandlerType *handler, 
00066                   nuint32 min_args = 0, Style style = GNU_STYLE);
00067             
00071             ~NGetOpt(void);
00072             
00077             void setStyle(Style style);
00078             
00084             Style getStyle(void) const;
00085             
00097             NGetOpt &add(const NString &opt_short, const NString &opt_long, 
00098                         bool opt_opt, const NString &help, 
00099                         typename NOpt<HandlerType>::Handler handler);
00100             
00106             NGetOpt &add(const NOpt<HandlerType> &opt);
00107             
00112             bool proccess(void);
00113             
00117             void help(void);
00118             
00119       private:
00120             int m_argc;
00121             char **m_argv;
00122             HandlerType *m_handler;
00123             Style m_style;
00124             NOptList m_opts;
00125             NString m_style_str_short;
00126             NString m_style_str_long;
00127             NOptList m_passed;
00128             nint32 m_min_args;
00129             
00130             NOpt<HandlerType> getOptByName(const NString &str);
00131             bool isLongOpt(const NString &str) const;
00132             bool isShortOpt(const NString &str) const;
00133             
00134             NException valueErr(const NOpt<HandlerType> *opt);
00135             char **addValue(NOpt<HandlerType> *opt, nint32 pos, char **list);
00136             void checkRequired(void);
00137             
00138             
00139             void showUsage(void);
00140             void showHelp(void);
00141             
00142             NGetOpt(const NGetOpt &);
00143             NGetOpt &operator=(const NGetOpt &);
00144 };
00145 
00146 
00147 template <typename HandlerType>
00148 NGetOpt<HandlerType>::NGetOpt(int argc, char **argv, HandlerType *handler, 
00149       nuint32 min_args, Style style)
00150                   : NObject(),
00151                   m_argc(argc - 1),
00152                   m_argv(argv),
00153                   m_handler(handler),
00154                   m_style(style),
00155                   m_opts(),
00156                   m_style_str_short(),
00157                   m_style_str_long(),
00158                   m_passed(),
00159                   m_min_args(min_args)
00160                   
00161 {
00162       assert(handler);
00163       
00164       if (m_style == GNU_STYLE) {
00165             m_style_str_short = "-";
00166             m_style_str_long = "--";
00167       }
00168       else {
00169             if (m_style == BSD_STYLE) {
00170                   m_style_str_short = "-";
00171                   m_style_str_long = "-";
00172             }
00173             else {
00174                   m_style_str_short = "/";
00175                   m_style_str_long = "/";
00176             }
00177       }
00178 }
00179 
00180 
00181 template <typename HandlerType>
00182 NGetOpt<HandlerType>::~NGetOpt(void) {
00183 
00184 }
00185 
00186 
00187 template <typename HandlerType>
00188 void NGetOpt<HandlerType>::setStyle(Style style) {
00189       m_style = style;
00190 }
00191 
00192 
00193 template <typename HandlerType>
00194 typename NGetOpt<HandlerType>::Style NGetOpt<HandlerType>::getStyle(void) const {
00195       return m_style;
00196 }
00197 
00198 
00199 template <typename HandlerType>
00200 NGetOpt<HandlerType> &NGetOpt<HandlerType>::add(const NString &opt_short, const NString &opt_long, 
00201                                     bool opt_opt, const NString &opt_help, 
00202                                     typename NOpt<HandlerType>::Handler handler)
00203 {
00204       NOpt<HandlerType> opt(opt_short, opt_long, opt_opt, opt_help, handler);
00205       NDebug::print() << "Adding options";
00206       NDebug::print() << "Option: " << opt_short << ". Value: " << opt_long << 
00207             "(" << opt_help << ")";
00208       
00209       
00210       
00211       return add(opt);
00212 }
00213 
00214 
00215 template <typename HandlerType>
00216 NGetOpt<HandlerType> &NGetOpt<HandlerType>::add(const NOpt<HandlerType> &opt) {
00217       if (!m_opts.contains(opt)) {
00218             m_opts.append(opt);
00219       }
00220       else {
00221             NWarning::print() << "Trying to insert a value '-" << opt.getShort() 
00222                         << "' [ --" << opt.getLong() << " ] already in the argument list";
00223       }
00224       return *this;
00225 }
00226 
00227 
00228 template <typename HandlerType>
00229 bool NGetOpt<HandlerType>::isLongOpt(const NString &str) const {
00230       NDebug::print() << " ---> "  << m_style_str_long << " & " << str;
00231       
00232       if (str.compare(0, m_style_str_long.length(), m_style_str_long)) {
00233             return true;      
00234       }
00235       
00236       return false;
00237 }
00238 
00239 
00240 template <typename HandlerType>
00241 bool NGetOpt<HandlerType>::isShortOpt(const NString &str) const {
00242       if (str.compare(0, m_style_str_short.length(), m_style_str_short)) {
00243             if (!isLongOpt(str)) { 
00244                   return true;
00245             }
00246       }
00247       
00248       return false;
00249 }
00250 
00251 
00252 template <typename HandlerType>
00253 NOpt<HandlerType> NGetOpt<HandlerType>::getOptByName(const NString &str) {
00254       NString opt_str;
00255       NString cmd_str;
00256       typename NOptList::iterator i = m_opts.begin();
00257       NOpt<HandlerType> ret;
00258       
00259       bool is_short = false;
00260       nuint32 opt_length = m_style_str_long.length();
00261 
00262       NDebug::print() << "Looking for option: " << str;
00263       if (isShortOpt(str)) {
00264             NDebug::print() << "Given option is short";
00265             is_short = true;
00266             opt_length = m_style_str_short.length();
00267       }
00268       else {
00269             NDebug::print() << "Given option is not short, checking if it's long";
00270             if (!isLongOpt(str)) { 
00271                   NString msg = "Option ";
00272                   msg = msg + str + " is not valid";
00273                   throw NException(msg, NException::BASE);
00274             }
00275       }
00276 
00277       cmd_str = str.substr(opt_length, str.length() - opt_length);
00278       for (i = m_opts.begin(); i != m_opts.end(); i++) {
00279             opt_str = is_short ? i->getShort() : i->getLong();
00280                   
00281             NDebug::print() << "Comparing: " << cmd_str << "(" << cmd_str.length()
00282                   << ") with " << opt_str << "(" << opt_str.length() << ")";
00283             
00284             if (cmd_str == opt_str) {
00285                   NDebug::print() << "Ok, found!";
00286                   ret = *i;
00287                   break;
00288             }
00289       }
00290       
00291       return ret;
00292 }
00293 
00294 template <typename HandlerType>
00295 NException NGetOpt<HandlerType>::valueErr(const NOpt<HandlerType> *opt) { 
00296       NString msg = "The option ";
00297             
00298       if (opt->getShort() != "") { 
00299             msg = msg + "'" + opt->getShort() + "'";
00300       }
00301 
00302       if (opt->getLong() != "") {
00303             msg = msg + " [ " + opt->getLong() + " ] ";
00304       }
00305 
00306       msg += "requires an argument but it was not given";
00307       return NException(msg, NException::BASE);
00308 }
00309 
00310 
00311 
00312 template <typename HandlerType>
00313 char **NGetOpt<HandlerType>::addValue(NOpt<HandlerType> *opt, nint32 pos, char **list) { 
00314       NString tmp;
00315       assert(opt);
00316       
00317       list++;
00318       if (!*list || isLongOpt(*list) || isShortOpt(*list)) { 
00319             throw valueErr(opt);
00320       }
00321       
00322       opt->addValue(*list);
00323       return list;
00324 }
00325 
00326 
00327 template <typename HandlerType>
00328 void NGetOpt<HandlerType>::showUsage(void) { 
00329       NMessage::print() << LIGHT_WHITE << "Usage:";
00330       for (typename NOptList::iterator i = m_opts.begin(); 
00331                 i != m_opts.end(); 
00332                 i++) 
00333       {
00334             NString tmp;
00335             NString msg = "\t"; 
00336             
00337             if (i->getShort() != "") { 
00338                   msg = msg + LIGHT_GREEN + "-" + i->getShort();
00339                   
00340                   if (i->getLong() != "") {
00341                         msg = msg + RESET + " [ " + LIGHT_GREEN + "--" + i->getLong() + RESET + " ] ";
00342                   }
00343             }
00344             else { 
00345                   if (i->getLong() != "") {
00346                         msg = msg + LIGHT_GREEN + "--" + i->getLong() + RESET;
00347                   }
00348             }
00349 
00350             if (i->hasOpt()) { 
00351                   msg = msg + LIGHT_CYAN + "< value > ";
00352             }
00353       
00354             NMessage::print() << msg;
00355       }
00356 }
00357 
00358 
00359 template <typename HandlerType>
00360 void NGetOpt<HandlerType>::showHelp(void) { 
00361       NMessage::print() << LIGHT_WHITE << "Help:";
00362       for (typename NOptList::iterator i = m_opts.begin(); 
00363                 i != m_opts.end(); 
00364                 i++) 
00365       {
00366             NString msg = "\t"; 
00367             
00368             if (i->getLong() != "") {
00369                   msg = msg + LIGHT_GREEN + " --" + i->getLong() + RESET + " ";
00370             }
00371             
00372             if (i->getShort() != "") { 
00373                   msg = msg + "(" + LIGHT_GREEN "-" + i->getShort() + RESET + " short option)";
00374                   
00375             }
00376             
00377             msg += "\n\t\t";
00378             msg += i->getHelp();
00379             msg += "\n";
00380 
00381             NMessage::print() << msg;
00382       }
00383 }
00384 
00385 template <typename HandlerType>
00386 void NGetOpt<HandlerType>::help(void) { 
00387       showUsage();
00388       NMessage::print();
00389       showHelp();
00390 }
00391 
00392 
00393 template <typename HandlerType>
00394 bool NGetOpt<HandlerType>::proccess(void) {
00395       typename NOpt<HandlerType>::Handler method;
00396       NOpt<HandlerType> opt;
00397       NString tmp;
00398       char **local_argv = m_argv;
00399       
00400       if (m_argc <= m_min_args) {
00401             help();
00402             return false;
00403       }
00404       
00405       local_argv++;
00406       for (nint32 i = 1; i <= m_argc; i++, local_argv++) {
00407             tmp = *local_argv;
00408             
00409             opt = getOptByName(tmp);
00410             if (!opt.isNull()) {
00411                   if (opt.hasOpt()) {
00412                         local_argv = addValue(&opt, i, local_argv);
00413                         i++;
00414                   }
00415                   
00416                   m_passed.append(opt);
00417             }
00418             else { 
00419                   NWarning::print() << "Invalid option " << tmp;
00420                   help();
00421                   
00422                   return false;
00423                   
00424             }
00425       }
00426       
00427       // Executes each given parameter
00428       for (typename NOptList::iterator i = m_passed.begin(); 
00429                 i != m_passed.end(); 
00430                 i++) 
00431       {
00432             method = i->getHandler();
00433             if (!method) { 
00434                   help();
00435                   return false;
00436             }
00437             else {
00438                   if (!(m_handler->*method)(*i)) {
00439                         return false;
00440                   };
00441             }
00442       }
00443       
00444       return true;
00445       
00446 }
00447 
00448 #endif // NGETOPT_HPP

Generated on Wed Mar 5 23:10:35 2008 for NemesisUtilitiesSystem by  doxygen 1.5.4