Gnash
0.8.10
|
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: