Gnash  0.8.10
arg_parser.h
Go to the documentation of this file.
00001 //  Arg_parser - A POSIX/GNU command line argument parser.
00002 //    Copyright (C) 2006, 2007, 2008, 2009, 2010 Antonio Diaz Diaz.
00003 //    Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
00004 //
00005 //    This program is free software: you can redistribute it and/or modify
00006 //    it under the terms of the GNU General Public License as published by
00007 //    the Free Software Foundation, either version 3 of the License, or
00008 //    (at your option) any later version.
00009 //
00010 //    This program is distributed in the hope that it will be useful,
00011 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //    GNU General Public License for more details.
00014 //
00015 //    You should have received a copy of the GNU General Public License
00016 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 //
00019 //  Arg_parser reads the arguments in `argv' and creates a number of
00020 //    option codes, option arguments and non-option arguments.
00021 //
00022 //    In case of error, `error' returns a non-empty error message.
00023 //
00024 //    `options' is an array of `struct Option' terminated by an element
00025 //    containing a code which is zero. A null name means a short-only
00026 //    option. A code value outside the unsigned char range means a
00027 //    long-only option.
00028 //
00029 //    Arg_parser normally makes it appear as if all the option arguments
00030 //    were specified before all the non-option arguments for the purposes
00031 //    of parsing, even if the user of your program intermixed option and
00032 //    non-option arguments. If you want the arguments in the exact order
00033 //    the user typed them, call `Arg_parser' with `in_order' = true.
00034 //
00035 //    The argument `--' terminates all options; any following arguments are
00036 //    treated as non-option arguments, even if they begin with a hyphen.
00037 //
00038 //    The syntax for optional option arguments is `-<short_option><argument>'
00039 //    (without whitespace), or `--<long_option>=<argument>'.
00040 
00041 // This class has been modified with a templated parser.argument<>
00042 // method, allowing typesafe handling of different return types, and
00043 // saving using strto* on the user side. I've added an exception class
00044 // because I'd like to know if we call an argument outside the range
00045 // of argument - there's no reasonable situation in which that would 
00046 // happen. <bwy>
00047 
00048 #include "dsodefs.h"
00049 #include <vector>
00050 #include <sstream>
00051 
00052 class Arg_parser
00053 {
00054 public:
00055     enum Has_arg { no, yes, maybe };
00056     
00057     struct Option
00058     {
00059         int code;                       // Short option letter or code ( code != 0 )
00060         const char * name;              // Long option name (maybe null)
00061         Has_arg has_arg;
00062     };
00063     
00064     class ArgParserException : public std::exception
00065     {
00066     public:
00067         ArgParserException(const std::string& s)
00068             :
00069             _msg(s)
00070         {}
00071         
00072         virtual ~ArgParserException() throw() {}
00073         
00074         const char* what() const throw() { return _msg.c_str(); }
00075         
00076     private:
00077         
00078         std::string _msg;
00079     };
00080     
00081 private:
00082     struct Record
00083     {
00084         int code;
00085         std::string argument;
00086         Record( const int c = 0 ) : code( c ) {}
00087     };
00088     
00089     std::string _error;
00090     std::vector< Record > data;
00091     
00092     bool parse_long_option( const char * const opt, const char * const arg,
00093                             const Option options[], int & argind ) throw();
00094     bool parse_short_option( const char * const opt, const char * const arg,
00095                              const Option options[], int & argind ) throw();
00096     
00097 public:
00098     DSOEXPORT Arg_parser( const int argc, const char * const argv[],
00099                           const Option options[], const bool in_order = false ) throw();
00100     
00101     // Restricted constructor. Parses a single token and argument (if any)
00102     DSOEXPORT Arg_parser( const char * const opt, const char * const arg,
00103                           const Option options[] ) throw();
00104     
00105     const std::string & error() const throw() { return _error; }
00106     
00107     // The number of arguments parsed (may be different from argc)
00108     int arguments() const throw() { return data.size(); }
00109     
00110     // If code( i ) is 0, argument( i ) is a non-option.
00111     // Else argument( i ) is the option's argument (or empty).
00112     int code( const int i ) const throw()
00113     {
00114         if( i >= 0 && i < arguments() ) return data[i].code;
00115         else return 0;
00116     }
00117     
00118     std::string argument(const int i) const throw(ArgParserException)
00119     {
00120         if( i >= 0 && i < arguments() ) return data[i].argument;
00121         else return _error;
00122     }    
00123     
00124     template<typename T>
00125     T argument(const int i) const throw (ArgParserException)
00126     {
00127         T t = 0;
00128         if( i >= 0 && i < arguments() )
00129             {
00130                 std::istringstream in(data[i].argument);
00131                 in >> t;
00132                 return t;
00133             }
00134         else throw ArgParserException("Code out of range");
00135     }  
00136 };
00137 
00138 
00139 // local Variables:
00140 // mode: C++
00141 // indent-tabs-mode: t
00142 // End: