GCC Code Coverage Report


Directory: ./
File: apps/volk_option_helpers.cc
Date: 2023-10-23 23:10:04
Exec Total Coverage
Lines: 0 147 0.0%
Functions: 0 11 0.0%
Branches: 0 220 0.0%

Line Branch Exec Source
1 /* -*- c++ -*- */
2 /*
3 * Copyright 2018-2020 Free Software Foundation, Inc.
4 *
5 * This file is part of VOLK
6 *
7 * SPDX-License-Identifier: LGPL-3.0-or-later
8 */
9
10
11 #include "volk_option_helpers.h"
12
13 #include <limits.h> // IWYU pragma: keep
14 #include <cstdlib> // IWYU pragma: keep
15 #include <cstring> // IWYU pragma: keep
16 #include <exception> // for exception
17 #include <iostream> // for operator<<, endl, basic_ostream, cout, ostream
18 #include <utility> // for pair
19
20 /*
21 * Option type
22 */
23 option_t::option_t(std::string t_longform,
24 std::string t_shortform,
25 std::string t_msg,
26 void (*t_callback)())
27 : longform("--" + t_longform),
28 shortform("-" + t_shortform),
29 msg(t_msg),
30 callback(t_callback)
31 {
32 option_type = VOID_CALLBACK;
33 }
34
35 option_t::option_t(std::string t_longform,
36 std::string t_shortform,
37 std::string t_msg,
38 void (*t_callback)(int))
39 : longform("--" + t_longform),
40 shortform("-" + t_shortform),
41 msg(t_msg),
42 callback((void (*)())t_callback)
43 {
44 option_type = INT_CALLBACK;
45 }
46
47 option_t::option_t(std::string t_longform,
48 std::string t_shortform,
49 std::string t_msg,
50 void (*t_callback)(float))
51 : longform("--" + t_longform),
52 shortform("-" + t_shortform),
53 msg(t_msg),
54 callback((void (*)())t_callback)
55 {
56 option_type = FLOAT_CALLBACK;
57 }
58
59 option_t::option_t(std::string t_longform,
60 std::string t_shortform,
61 std::string t_msg,
62 void (*t_callback)(bool))
63 : longform("--" + t_longform),
64 shortform("-" + t_shortform),
65 msg(t_msg),
66 callback((void (*)())t_callback)
67 {
68 option_type = BOOL_CALLBACK;
69 }
70
71 option_t::option_t(std::string t_longform,
72 std::string t_shortform,
73 std::string t_msg,
74 void (*t_callback)(std::string))
75 : longform("--" + t_longform),
76 shortform("-" + t_shortform),
77 msg(t_msg),
78 callback((void (*)())t_callback)
79 {
80 option_type = STRING_CALLBACK;
81 }
82
83 option_t::option_t(std::string t_longform,
84 std::string t_shortform,
85 std::string t_msg,
86 std::string t_printval)
87 : longform("--" + t_longform),
88 shortform("-" + t_shortform),
89 msg(t_msg),
90 printval(t_printval)
91 {
92 option_type = STRING;
93 }
94
95
96 /*
97 * Option List
98 */
99
100 option_list::option_list(std::string program_name) : d_program_name(program_name)
101 {
102 d_internal_list = std::vector<option_t>();
103 }
104
105
106 void option_list::add(option_t opt) { d_internal_list.push_back(opt); }
107
108 void option_list::parse(int argc, char** argv)
109 {
110 for (int arg_number = 0; arg_number < argc; ++arg_number) {
111 for (std::vector<option_t>::iterator this_option = d_internal_list.begin();
112 this_option != d_internal_list.end();
113 this_option++) {
114 int int_val = INT_MIN;
115 if (this_option->longform == std::string(argv[arg_number]) ||
116 this_option->shortform == std::string(argv[arg_number])) {
117
118 if (d_present_options.count(this_option->longform) == 0) {
119 d_present_options.insert(
120 std::pair<std::string, int>(this_option->longform, 1));
121 } else {
122 d_present_options[this_option->longform] += 1;
123 }
124 switch (this_option->option_type) {
125 case VOID_CALLBACK:
126 this_option->callback();
127 break;
128 case INT_CALLBACK:
129 try {
130 int_val = atoi(argv[++arg_number]);
131 ((void (*)(int))this_option->callback)(int_val);
132 } catch (std::exception& exc) {
133 std::cout << "An int option can only receive a number"
134 << std::endl;
135 throw std::exception();
136 };
137 break;
138 case FLOAT_CALLBACK:
139 try {
140 double double_val = atof(argv[++arg_number]);
141 ((void (*)(float))this_option->callback)(double_val);
142 } catch (std::exception& exc) {
143 std::cout << "A float option can only receive a number"
144 << std::endl;
145 throw std::exception();
146 };
147 break;
148 case BOOL_CALLBACK:
149 try {
150 if (arg_number == (argc - 1)) { // this is the last arg
151 int_val = 1;
152 } else { // sneak a look at the next arg since it's present
153 char* next_arg = argv[arg_number + 1];
154 if ((strncmp(next_arg, "-", 1) == 0) ||
155 (strncmp(next_arg, "--", 2) == 0)) {
156 // the next arg is actually an arg, the bool is just
157 // present, set to true
158 int_val = 1;
159 } else if (strncmp(next_arg, "true", 4) == 0) {
160 int_val = 1;
161 } else if (strncmp(next_arg, "false", 5) == 0) {
162 int_val = 0;
163 } else {
164 // we got a number or a string.
165 // convert it to a number and depend on the catch to
166 // report an error condition
167 int_val = (bool)atoi(argv[++arg_number]);
168 }
169 }
170 } catch (std::exception& e) {
171 int_val = INT_MIN;
172 };
173 if (int_val == INT_MIN) {
174 std::cout
175 << "option: '" << argv[arg_number - 1]
176 << "' -> received an unknown value. Boolean "
177 "options should receive one of '0', '1', 'true', 'false'."
178 << std::endl;
179 throw std::exception();
180 } else if (int_val) {
181 ((void (*)(bool))this_option->callback)(int_val);
182 }
183 break;
184 case STRING_CALLBACK:
185 try {
186 ((void (*)(std::string))this_option->callback)(
187 argv[++arg_number]);
188 } catch (std::exception& exc) {
189 throw std::exception();
190 };
191 case STRING:
192 std::cout << this_option->printval << std::endl;
193 break;
194 }
195 }
196 }
197 if (std::string("--help") == std::string(argv[arg_number]) ||
198 std::string("-h") == std::string(argv[arg_number])) {
199 d_present_options.insert(std::pair<std::string, int>("--help", 1));
200 help();
201 }
202 }
203 }
204
205 bool option_list::present(std::string option_name)
206 {
207 if (d_present_options.count("--" + option_name)) {
208 return true;
209 } else {
210 return false;
211 }
212 }
213
214 void option_list::help()
215 {
216 std::cout << d_program_name << std::endl;
217 std::cout << " -h [ --help ] \t\tdisplay this help message" << std::endl;
218 for (std::vector<option_t>::iterator this_option = d_internal_list.begin();
219 this_option != d_internal_list.end();
220 this_option++) {
221 std::string help_line(" ");
222 if (this_option->shortform == "-") {
223 help_line += this_option->longform + " ";
224 } else {
225 help_line += this_option->shortform + " [ " + this_option->longform + " ]";
226 }
227
228 switch (help_line.size() / 8) {
229 case 0:
230 help_line += "\t";
231 case 1:
232 help_line += "\t";
233 case 2:
234 help_line += "\t";
235 case 3:
236 help_line += "\t";
237 }
238 help_line += this_option->msg;
239 std::cout << help_line << std::endl;
240 }
241 }
242