1 #include <climits>
2 #include <cstring>
3 #include <cstdlib>
4 #include "xr_cl_parser.h"
5 
cl_parser()6 cl_parser::cl_parser(): m_options(0),
7 	m_num_options(0), m_num_params(0) {}
8 
~cl_parser()9 cl_parser::~cl_parser()
10 {
11 	delete[] m_options;
12 }
13 
parse(int argc,const char * const argv[],int optc,const option_desc * optv)14 bool cl_parser::parse(int argc, const char* const argv[],
15 		int optc, const option_desc* optv)
16 {
17 	m_options = new option[argc];
18 	m_argc = size_t(argc & INT_MAX);
19 
20 	size_t opt_idx = 0, param_idx = size_t(argc & INT_MAX) - 1;
21 	for (++argv; argc > 1; ++argv, --argc) {
22 		if ((*argv)[0] != '-') {
23 			m_options[param_idx].name = *argv;
24 			--param_idx;
25 			++m_num_params;
26 			continue;
27 		}
28 		bool valid = false;
29 		const option_desc* desc = optv;
30 		for (int j = optc; j > 0; --j, ++desc) {
31 			if (std::strcmp(*argv, desc->name) != 0)
32 				continue;
33 			valid = true;
34 			option& opt = m_options[opt_idx++];
35 			opt.name = desc->name;
36 			opt.type = desc->type;
37 			if (opt.type == OT_BOOL) {
38 				opt.v_bool = true;
39 			} else if (--argc <= 1) {
40 				return false;
41 			} else {
42 				++argv;
43 				switch (opt.type) {
44 				case OT_STRING:
45 					opt.v_string = *argv;
46 					break;
47 				case OT_INTEGER:
48 					opt.v_integer = std::atoi(*argv);
49 					break;
50 				case OT_FLOAT:
51 					opt.v_float = float(std::atof(*argv));
52 					break;
53 				default:
54 					return false;
55 				}
56 			}
57 			break;
58 		}
59 		if (!valid)
60 			return false;
61 	}
62 	m_num_options = opt_idx;
63 	return true;
64 }
65 
find_option(const char * name) const66 const cl_parser::option* cl_parser::find_option(const char* name) const
67 {
68 	for (const option *opt = m_options, *end = opt + m_num_options;
69 			opt != end; ++opt) {
70 		if (std::strcmp(opt->name, name) == 0)
71 			return opt;
72 	}
73 	return 0;
74 }
75 
get_bool(const char * name) const76 bool cl_parser::get_bool(const char* name) const
77 {
78 	const option* opt = find_option(name);
79 	return opt && opt->type == OT_BOOL;
80 }
81 
get_string(const char * name,const char * & value) const82 bool cl_parser::get_string(const char* name, const char*& value) const
83 {
84 	const option* opt = find_option(name);
85 	if (opt && opt->type == OT_STRING) {
86 		value = opt->v_string;
87 		return true;
88 	}
89 	return false;
90 }
91 
get_string(const char * name,std::string & value) const92 bool cl_parser::get_string(const char* name, std::string& value) const
93 {
94 	const option* opt = find_option(name);
95 	if (opt && opt->type == OT_STRING) {
96 		value = opt->v_string;
97 		return true;
98 	}
99 	return false;
100 }
101 
get_integer(const char * name,int & value) const102 bool cl_parser::get_integer(const char* name, int& value) const
103 {
104 	const option* opt = find_option(name);
105 	if (opt && opt->type == OT_INTEGER) {
106 		value = opt->v_integer;
107 		return true;
108 	}
109 	return false;
110 }
111