1 /* COPYING ****************************************************************** 2 For copyright and licensing terms, see the file named COPYING. 3 // ************************************************************************** 4 */ 5 6 #if !defined(INCLUDE_POPT_H) 7 #define INCLUDE_POPT_H 8 9 #include <vector> 10 #include <list> 11 #include <string> 12 #include <cstdio> 13 14 namespace popt { 15 struct error { errorerror16 error(const char * a, const char * m) : arg(a), msg(m) {} 17 const char * arg, * msg; 18 }; 19 class processor; 20 struct definition { 21 public: definitiondefinition22 definition() {} 23 virtual bool execute(processor &, char c) = 0; 24 virtual bool execute(processor &, char c, const char * s) = 0; 25 virtual bool execute(processor &, const char * s) = 0; 26 virtual ~definition() = 0; 27 }; 28 class processor { 29 public: 30 processor(const char * n, definition & d, std::vector<const char *> & f); ~processor()31 virtual ~processor() {} 32 virtual const char * next_arg() = 0; 33 void process(bool strictly_options_before_arguments, bool single_dash_long_options = false) { 34 while (const char * arg = next_arg()) { 35 if (is_stopped) break; 36 if (0 == slash && ('-' == arg[0] 37 #if defined(__OS2__) || defined(__WIN32__) || defined(__NT__) 38 || '/' == arg[0] // If the compiler is hosted on these platforms, this can also be the option character. 39 #endif 40 )) 41 slash = arg[0]; 42 if (!slash || slash != arg[0]) { 43 file_vector.push_back(arg); 44 if (strictly_options_before_arguments) 45 slash = EOF; 46 } else if (arg[1] == slash) { 47 if (!arg[2]) 48 slash = EOF; 49 else if (!def.execute(*this, arg + 2)) 50 throw error(arg, "unrecognized option"); 51 } else if (!single_dash_long_options || !def.execute(*this, arg + 1)) { 52 for ( const char * p(arg + 1); *p; ++p ) { 53 if (def.execute(*this, *p, p + 1)) 54 break; 55 if (!def.execute(*this, *p)) 56 throw error(arg, "unrecognized option(s)"); 57 } 58 } 59 } 60 } stopped()61 bool stopped() const { return is_stopped; } stop()62 void stop() { is_stopped = true; } 63 std::vector<const char *> & file_vector; 64 const char * name; 65 protected: 66 int slash; 67 definition & def; 68 bool is_stopped; 69 }; 70 template <class InputIterator> class arg_processor : public processor { 71 public: arg_processor(InputIterator b,InputIterator e,const char * n,definition & d,std::vector<const char * > & f)72 arg_processor(InputIterator b, InputIterator e, const char * n, definition & d, std::vector<const char *> & f) : processor(n, d, f), current(b), end(e) {} next_arg()73 const char * next_arg() 74 { 75 if (current >= end) return nullptr; 76 return *current++; 77 } 78 protected: 79 InputIterator current, end; 80 }; 81 struct table_definition : public definition { 82 public: table_definitiontable_definition83 table_definition(unsigned c, definition * const * v, const char * d) : definition(), count(c), array(v), description(d) {} 84 virtual void long_usage(); 85 virtual void help(); 86 virtual ~table_definition(); 87 protected: 88 virtual bool execute(processor &, char c); 89 virtual bool execute(processor &, char c, const char * s); 90 virtual bool execute(processor &, const char * s); 91 void gather_combining_shorts(std::string &); 92 unsigned count; 93 definition * const *array; 94 const char * description; 95 }; 96 struct top_table_definition : public table_definition { 97 public: top_table_definitiontop_table_definition98 top_table_definition(unsigned c, definition * const * v, const char * d, const char * a) : table_definition(c, v, d), arguments_description(a) {} 99 virtual ~top_table_definition(); 100 protected: 101 void do_usage(processor &); 102 void do_help(processor &); 103 const char * arguments_description; 104 using table_definition::execute; 105 virtual bool execute(processor &, char c); 106 virtual bool execute(processor &, const char * s); 107 }; 108 struct named_definition : public definition { 109 public: named_definitionnamed_definition110 named_definition(char s, const char * l, const char * a, const char * d) : short_name(s), long_name(l), optarg_description(a), description(d) {} query_args_descriptionnamed_definition111 const char * query_args_description() const { return optarg_description; } query_descriptionnamed_definition112 const char * query_description() const { return description; } query_short_namenamed_definition113 char query_short_name() const { return short_name; } query_long_namenamed_definition114 const char * query_long_name() const { return long_name; } 115 virtual ~named_definition() = 0; 116 protected: 117 char short_name; 118 const char * long_name; 119 const char * optarg_description; 120 const char * description; 121 }; 122 struct simple_named_definition : public named_definition { 123 public: simple_named_definitionsimple_named_definition124 simple_named_definition(char s, const char * l, const char * d) : named_definition(s, l, nullptr, d) {} 125 virtual ~simple_named_definition() = 0; 126 protected: 127 virtual void action(processor &) = 0; 128 virtual bool execute(processor & proc, char c); 129 virtual bool execute(processor &, char c, const char * s); 130 virtual bool execute(processor & proc, const char * s); 131 }; 132 struct compound_named_definition : public named_definition { 133 public: compound_named_definitioncompound_named_definition134 compound_named_definition(char s, const char * l, const char * a, const char * d) : named_definition(s, l, a, d) {} 135 virtual ~compound_named_definition() = 0; 136 protected: 137 virtual void action(processor &, const char *) = 0; 138 virtual bool execute(processor & proc, char c); 139 virtual bool execute(processor &, char c, const char * s); 140 virtual bool execute(processor & proc, const char * s); 141 }; 142 struct string_definition : public compound_named_definition { 143 public: string_definitionstring_definition144 string_definition(char s, const char * l, const char * a, const char * d, const char * & v) : compound_named_definition(s, l, a, d), value(v) {} 145 virtual ~string_definition(); 146 protected: 147 virtual void action(processor &, const char *); 148 const char * & value; 149 }; 150 struct string_list_definition : public compound_named_definition { 151 public: 152 typedef std::list<std::string> list_type; string_list_definitionstring_list_definition153 string_list_definition(char s, const char * l, const char * a, const char * d, list_type & v) : compound_named_definition(s, l, a, d), value_list(v) {} 154 virtual ~string_list_definition(); 155 protected: 156 virtual void action(processor &, const char *); 157 list_type & value_list; 158 }; 159 struct bool_definition : public simple_named_definition { 160 public: bool_definitionbool_definition161 bool_definition(char s, const char * l, const char * d, bool & v) : simple_named_definition(s, l, d), value(v) {} 162 virtual ~bool_definition(); 163 protected: 164 virtual void action(processor &); 165 bool & value; 166 }; 167 struct integral_definition : public compound_named_definition { 168 public: integral_definitionintegral_definition169 integral_definition(char s, const char * l, const char * a, const char * d) : compound_named_definition(s, l, a, d), set(false) {} 170 virtual ~integral_definition() = 0; is_setintegral_definition171 bool is_set() const { return set; } 172 protected: 173 bool set; 174 }; 175 struct bool_string_definition : public integral_definition { 176 public: bool_string_definitionbool_string_definition177 bool_string_definition(char s, const char * l, const char * d, bool & v) : integral_definition(s, l, a, d), value(v) {} 178 virtual ~bool_string_definition(); 179 protected: 180 static const char a[]; 181 virtual void action(processor &, const char *); 182 bool & value; 183 }; 184 struct number_definition : public integral_definition { 185 public: number_definitionnumber_definition186 number_definition(char s, const char * l, const char * a, const char * d, int b) : integral_definition(s, l, a, d), base(b) {} 187 protected: 188 virtual void action(processor &, const char *) = 0; 189 int base; 190 }; 191 struct unsigned_number_definition : public number_definition { 192 public: unsigned_number_definitionunsigned_number_definition193 unsigned_number_definition(char s, const char * l, const char * a, const char * d, unsigned long & v, int b) : number_definition(s, l, a, d, b), value(v) {} 194 virtual ~unsigned_number_definition(); 195 protected: 196 virtual void action(processor &, const char *); 197 unsigned long & value; 198 }; 199 struct signed_number_definition : public number_definition { 200 public: signed_number_definitionsigned_number_definition201 signed_number_definition(char s, const char * l, const char * a, const char * d, signed long & v, int b) : number_definition(s, l, a, d, b), value(v) {} 202 virtual ~signed_number_definition(); 203 protected: 204 virtual void action(processor &, const char *); 205 signed long & value; 206 }; 207 struct compound_2arg_named_definition : public named_definition { 208 public: compound_2arg_named_definitioncompound_2arg_named_definition209 compound_2arg_named_definition(char s, const char * l, const char * a, const char * d) : named_definition(s, l, a, d) {} 210 virtual ~compound_2arg_named_definition() = 0; 211 protected: 212 virtual void action(processor &, const char *, const char *) = 0; 213 virtual bool execute(processor & proc, char c); 214 virtual bool execute(processor &, char c, const char * s); 215 virtual bool execute(processor & proc, const char * s); 216 }; 217 struct string_pair_definition : public compound_2arg_named_definition { 218 public: string_pair_definitionstring_pair_definition219 string_pair_definition(char s, const char * l, const char * a, const char * d, const char * & v1, const char * & v2) : compound_2arg_named_definition(s, l, a, d), value1(v1), value2(v2) {} 220 virtual ~string_pair_definition(); 221 protected: 222 virtual void action(processor &, const char *, const char *); 223 const char * & value1, * & value2; 224 }; 225 struct string_pair_list_definition : public compound_2arg_named_definition { 226 public: 227 typedef std::pair<std::string,std::string> pair_type; 228 typedef std::list<pair_type> list_type; string_pair_list_definitionstring_pair_list_definition229 string_pair_list_definition(char s, const char * l, const char * a, const char * d, list_type & v) : compound_2arg_named_definition(s, l, a, d), value_list(v) {} 230 virtual ~string_pair_list_definition(); 231 protected: 232 virtual void action(processor &, const char *, const char *); 233 list_type & value_list; 234 }; 235 } 236 237 #endif 238