1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2002 by Diether Knof
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of
8 // the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 // You can find this license in the file 'gpl.txt'.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 // MA 02111-1307 USA
20 //
21 // Contact:
22 // Diether Knof dknof@posteo.de
23 //
24 //////////////////////////////////////////////////////////////////////////////
25
26 #include "getopt.h"
27
28 #include <iostream>
29 #include <cstdlib>
30 #include <climits>
31
32 using namespace GetOpt;
33
34 /**********************************************************************
35 *
36 * Option::Option()
37 *
38 * Parameters: -
39 *
40 * Result: -
41 *
42 * Description: Constructor
43 *
44 **********************************************************************/
Option()45 Option::Option() :
46 error_v(OK),
47 name_v(),
48 type_v(Syntax::BOOL),
49 value_v(),
50 value_string_v()
51 {
52 return ;
53 } // Option::Option()
54
55 /**********************************************************************
56 *
57 * Option::Option(Option const& option)
58 *
59 * Parameters: option - the other option
60 *
61 * Result: -
62 *
63 * Description: Constructor
64 *
65 **********************************************************************/
Option(Option const & option)66 Option::Option(Option const& option) :
67 error_v(option.error()),
68 name_v(option.name()),
69 type_v(option.type()),
70 value_v(),
71 value_string_v(option.value_string())
72 {
73 switch(option.type()) {
74 case Syntax::BOOL:
75 this->value_v.b = option.value(BOOL); // NOLINT cppcoreguidelines-pro-type-union-access
76 break;
77 case Syntax::INT:
78 this->value_v.i = option.value(INT); // NOLINT cppcoreguidelines-pro-type-union-access
79 break;
80 case Syntax::UNSIGNED:
81 this->value_v.u = option.value(UNSIGNED); // NOLINT cppcoreguidelines-pro-type-union-access
82 break;
83 case Syntax::DOUBLE:
84 // cppcheck-suppress assignBoolToFloat
85 this->value_v.d = option.value(DOUBLE); // NOLINT cppcoreguidelines-pro-type-union-access
86 break;
87 case Syntax::CHAR:
88 this->value_v.c = option.value(CHAR); // NOLINT cppcoreguidelines-pro-type-union-access
89 break;
90 case Syntax::BSTRING:
91 break;
92 case Syntax::END:
93 break;
94 } // switch(option.type())
95
96 return ;
97 } // Option::Option()
98
99 /**********************************************************************
100 *
101 * Option& Option::operator=(Option const& option)
102 *
103 * Parameters: option - the other option
104 *
105 * Result: -
106 *
107 * Description: Constructor
108 *
109 **********************************************************************/
110 Option&
operator =(Option const & option)111 Option::operator=(Option const& option)
112 {
113 this->error_v = option.error();
114 this->name_v = option.name();
115 this->value_string_v = option.value_string();
116
117 switch(option.type()) {
118 case Syntax::BOOL:
119 this->value_v.b = option.value(BOOL); // NOLINT cppcoreguidelines-pro-type-union-access
120 break;
121 case Syntax::INT:
122 this->value_v.i = option.value(INT); // NOLINT cppcoreguidelines-pro-type-union-access
123 break;
124 case Syntax::UNSIGNED:
125 this->value_v.u = option.value(UNSIGNED); // NOLINT cppcoreguidelines-pro-type-union-access
126 break;
127 case Syntax::DOUBLE:
128 // cppcheck-suppress assignBoolToFloat
129 this->value_v.d = option.value(DOUBLE); // NOLINT cppcoreguidelines-pro-type-union-access
130 break;
131 case Syntax::CHAR:
132 this->value_v.c = option.value(CHAR); // NOLINT cppcoreguidelines-pro-type-union-access
133 break;
134 case Syntax::BSTRING:
135 break;
136 case Syntax::END:
137 break;
138 } // switch(option.type())
139
140 return *this;
141 } // Option& Option::operator=(Option const& option)
142
143 /**********************************************************************
144 *
145 * Option::~Option()
146 *
147 * Parameters: -
148 *
149 * Result: -
150 *
151 * Description: Destructor -- nothing to do
152 *
153 **********************************************************************/
~Option()154 Option::~Option()
155 {
156 return ;
157 } // Option::~Option()
158
159 /**********************************************************************
160 *
161 * Option::Error Option::error() const
162 *
163 * Parameters: -
164 *
165 * Result: the error code
166 *
167 * Description: -> result
168 *
169 **********************************************************************/
170 Option::Error
error() const171 Option::error() const
172 {
173 return this->error_v;
174 } // Option::Error Option::error() const
175
176 /**********************************************************************
177 *
178 * bool Option::fail() const
179 *
180 * Parameters: -
181 *
182 * Result: wether the parsing is failed
183 *
184 * Description: -> result
185 *
186 **********************************************************************/
187 bool
fail() const188 Option::fail() const
189 {
190 return ((this->error() != OK)
191 && (this->error() != NO_OPTION));
192 } // bool Option::fail() const
193
194 /**********************************************************************
195 *
196 * Option::operator bool() const
197 *
198 * Parameters: -
199 *
200 * Result: whether another option could be parsed
201 * (with or without an error)
202 *
203 * Description: -> result
204 *
205 **********************************************************************/
operator bool() const206 Option::operator bool() const
207 {
208 return (this->error() != NO_OPTION);
209 } // Option::operator bool() const
210
211
212 /**********************************************************************
213 *
214 * std::string const& Option::name() const
215 *
216 * Parameters: -
217 *
218 * Result: the name of the option
219 *
220 * Description: -> result
221 *
222 **********************************************************************/
223 std::string const&
name() const224 Option::name() const
225 {
226 return this->name_v;
227 } // std::string const& Option::name() const
228
229 /**********************************************************************
230 *
231 * Syntax::Type Option::type() const
232 *
233 * Parameters: -
234 *
235 * Result: the type of the option
236 *
237 * Description: -> result
238 *
239 **********************************************************************/
240 Syntax::Type
type() const241 Option::type() const
242 {
243 return this->type_v;
244 } // Syntax::Type Option::type() const
245
246 /**********************************************************************
247 *
248 * bool Option::value(TypeBool) const
249 *
250 * Parameters: -
251 *
252 * Result: the bool value
253 *
254 * Description: -> result
255 *
256 **********************************************************************/
257 bool
value(TypeBool type) const258 Option::value(TypeBool type) const
259 {
260 return this->value_v.b; // NOLINT cppcoreguidelines-pro-type-union-access
261 } // bool Option::value(TypeBool) const
262
263 /**********************************************************************
264 *
265 * int Option::value(TypeInt) const
266 *
267 * Parameters: -
268 *
269 * Result: the int value
270 *
271 * Description: -> result
272 *
273 **********************************************************************/
274 int
value(TypeInt type) const275 Option::value(TypeInt type) const
276 {
277 return this->value_v.i; // NOLINT cppcoreguidelines-pro-type-union-access
278 } // int Option::value(TypeInt) const
279
280 /**********************************************************************
281 *
282 * unsigned Option::value(TypeUnsigned) const
283 *
284 * Parameters: -
285 *
286 * Result: the unsigned value
287 *
288 * Description: -> result
289 *
290 **********************************************************************/
291 unsigned
value(TypeUnsigned type) const292 Option::value(TypeUnsigned type) const
293 {
294 return this->value_v.u; // NOLINT cppcoreguidelines-pro-type-union-access
295 } // unsigned Option::value(TypeUnsigned) const
296
297 /**********************************************************************
298 *
299 * double Option::value(TypeDouble) const
300 *
301 * Parameters: -
302 *
303 * Result: the double value
304 *
305 * Description: -> result
306 *
307 **********************************************************************/
308 double
value(TypeDouble type) const309 Option::value(TypeDouble type) const
310 {
311 return this->value_v.d; // NOLINT cppcoreguidelines-pro-type-union-access
312 } // double Option::value(TypeDouble) const
313
314 /**********************************************************************
315 *
316 * char Option::value(TypeChar) const
317 *
318 * Parameters: -
319 *
320 * Result: the char value
321 *
322 * Description: -> result
323 *
324 **********************************************************************/
325 char
value(TypeChar type) const326 Option::value(TypeChar type) const
327 {
328 return this->value_v.b; // NOLINT cppcoreguidelines-pro-type-union-access
329 } // char Option::value(TypeChar) const
330
331 /**********************************************************************
332 *
333 * std::string const& Option::value(Typestring) const
334 *
335 * Parameters: -
336 *
337 * Result: the string value
338 *
339 * Description: -> result
340 *
341 **********************************************************************/
342 std::string const&
value(Typestring type) const343 Option::value(Typestring type) const
344 {
345 return this->value_string_v;
346 } // std::string const& Option::value(Typestring) const
347
348 /**********************************************************************
349 *
350 * std::string const& Option::value_string() const
351 *
352 * Parameters: -
353 *
354 * Result: the string value
355 *
356 * Description: -> result
357 *
358 **********************************************************************/
359 std::string const&
value_string() const360 Option::value_string() const
361 {
362 return this->value_string_v;
363 } // std::string const& Option::value_string() const
364
365 /**********************************************************************
366 *
367 * Option::Error Option::value_set(char const* argv)
368 *
369 * Parameters: argv - the argument with the valule
370 *
371 * Result: the errorcode
372 *
373 * Description: sets the value of the option
374 *
375 **********************************************************************/
376 Option::Error
value_set(char const * argv)377 Option::value_set(char const* argv)
378 {
379 this->error_v = OK;
380
381 switch(this->type()) {
382 case Syntax::BOOL:
383 // cannot be
384 this->error_v = UNKNOWN_ERROR;
385 break;
386 case Syntax::INT:
387 {
388 char* endptr;
389 this->value_v.i = strtol(argv, &endptr, 0); // NOLINT cppcoreguidelines-pro-type-union-access
390 if ((endptr == argv)
391 || (*endptr != '\0'))
392 this->error_v = FALSE_ARGUMENT;
393 break;
394 }
395 case Syntax::UNSIGNED:
396 {
397 char* endptr;
398 this->value_v.u = strtoul(argv, &endptr, 0); // NOLINT cppcoreguidelines-pro-type-union-access
399 if ((endptr == argv)
400 || (*endptr != '\0')
401 || (this->value_v.u == UINT_MAX) // NOLINT cppcoreguidelines-pro-type-union-access
402 || (argv[0] == '-')) // NOLINT cppcoreguidelines-pro-bounds-pointer-arithmetic
403 this->error_v = FALSE_ARGUMENT;
404 break;
405 }
406 case Syntax::DOUBLE:
407 {
408 char* endptr;
409 this->value_v.d = strtod(argv, &endptr); // NOLINT cppcoreguidelines-pro-type-union-access
410 if ((endptr == argv)
411 || (*endptr != '\0'))
412 this->error_v = FALSE_ARGUMENT;
413 break;
414 }
415 case Syntax::CHAR:
416 this->value_v.c = *argv; // NOLINT cppcoreguidelines-pro-type-union-access
417 if (argv[1] != '\0') // NOLINT cppcoreguidelines-pro-bounds-pointer-arithmetic
418 this->error_v = FALSE_ARGUMENT;
419 break;
420 case Syntax::BSTRING:
421 this->value_string_v = argv;
422 this->error_v = OK;
423 break;
424 case Syntax::END:
425 // cannot be
426 this->error_v = UNKNOWN_ERROR;
427 break;
428 }; // switch(this->type())
429
430 return this->error();
431 } // Option::Error Option::value_set(char const* argv)
432
433 /**********************************************************************
434 *
435 * std::ostream& operator<<(std::ostream& ostr, const Option::Error error)
436 *
437 * Parameters: ostr - the output stream
438 * error - the error
439 *
440 * Result: the output stream
441 *
442 * Description: output of the error to the stream
443 *
444 **********************************************************************/
445 std::ostream&
operator <<(std::ostream & ostr,Option::Error const error)446 operator<<(std::ostream& ostr, Option::Error const error)
447 {
448 switch(error) {
449 case Option::OK:
450 ostr << "ok";
451 break;
452 case Option::NO_OPTION:
453 ostr << "no option";
454 break;
455 case Option::UNKNOWN_OPTION:
456 ostr << "unknown option";
457 break;
458 case Option::FALSE_ARGUMENT:
459 ostr << "false argument";
460 break;
461 case Option::NO_ARGUMENT:
462 ostr << "no argument";
463 break;
464 case Option::UNKNOWN_ERROR:
465 ostr << "unknown error";
466 break;
467 } // switch(error)
468
469 return ostr;
470 } // std::ostream& operator<<(std::ostream& ostr, Option::Error const error)
471
472