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