FOUND Coverage Report


src/
File: command-line/parsing/parser.cpp
Date: 2025-11-20 21:57:26
Lines:
30/30
100.0%
Functions:
3/3
100.0%
Branches:
129/129
100.0%

Line Branch Exec Source
1 #include "command-line/parsing/parser.hpp"
2
3 #include <getopt.h>
4
5 #include <string>
6 #include <memory>
7 #include <iostream>
8
9 #include "common/logging.hpp"
10 #include "common/style.hpp"
11 #include "command-line/parsing/options.hpp"
12
13 /// This defines the global variable optind, used
14 /// for keeping track of parsing for command-line
15 /// arguments
16 int optind = 2;
17
18 /**
19 * Determines whether the current flag allows an optional argument AND
20 * if that argument exists
21 * To Fully Test this, you must:
22 * - Use the flag with an argument
23 * - Use the flag with no argument
24 * - Use the flag with an equals sign and value all in one token
25 * - Use the flag at the end of the command line
26 */
27 #define OPTIONAL_OPTARG() \
28 ((optarg == NULL && optind < argc && argv[optind][0] != '-') \
29 ? static_cast<bool>(optarg = argv[optind++]) \
30 : (optarg != NULL))
31
32 /**
33 * Assigns a flag with a required value
34 *
35 * @param options The options object that has the flag
36 * @param prop The name of the prop within options
37 * @param value The value to assign
38 * @param default Not used
39 */
40 #define REQ_ASSIGN(options, prop, value, default) \
41 options.prop = (value);
42
43 /**
44 * Assigns a flag with an optional value
45 *
46 * @param options The options object that has the flag
47 * @param prop The name of the prop within options
48 * @param value The value to assign
49 * @param default The default value
50 *
51 * @pre Must be used with FOUND_CLI_OPTION
52 */
53 #define OPT_ASSIGN(options, prop, value, default) \
54 if (OPTIONAL_OPTARG()) { \
55 options.prop = value; \
56 } else { \
57 options.prop = default; \
58 }
59
60 namespace found {
61
62 /// For macro processing
63 const char kNoDefaultArgument = 0;
64
65 13 CalibrationOptions ParseCalibrationOptions(int argc, char **argv) {
66 // Define an enum for each valid flag (command-line entry), which maps it from the name
67 // to an integer
68 enum class ClientOption {
69 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
70 prop,
71 CALIBRATION
72 #undef FOUND_CLI_OPTION
73 };
74
75 // Define an array of options, which defines the traits pertaining to each
76 // expected command-line entry
77 static option long_options[] = {
78 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
79 {name, \
80 defaultArg == kNoDefaultArgument ? required_argument : optional_argument, \
81 0, \
82 static_cast<int>(ClientOption::prop)},
83 CALIBRATION
84 #undef FOUND_CLI_OPTION
85 {0}
86 };
87
88 // Define our result, and iterator helpers
89
1/1
✓ Branch 1 taken 13 times.
13 CalibrationOptions options;
90 13 int index;
91 int option;
92
93 // Iterates through the list of command-line tokens and figures out
94 // what data to assign to which field in options. Note that the
95 // FOUND_CLI_OPTION defines the conversion already between any
96 // particular parameter (as a string) to its actual type
97
2/2
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 12 times.
34 while ((option = getopt_long(argc, argv, "", long_options, &index)) != -1) {
98
4/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1 times.
22 switch (option) {
99 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
100 case static_cast<int>(ClientOption::prop): \
101 ASSIGN(options, prop, converter, defaultArg) \
102 break;
103
5/5
✓ Branch 3 taken 7 times.
✓ Branch 6 taken 7 times.
✓ Branch 14 taken 7 times.
✓ Branch 17 taken 7 times.
✓ Branch 23 taken 7 times.
49 CALIBRATION
104 #undef FOUND_CLI_OPTION
105 1 default:
106
9/9
✓ Branch 3 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 16 taken 1 times.
✓ Branch 20 taken 1 times.
✓ Branch 23 taken 1 times.
✓ Branch 26 taken 1 times.
✓ Branch 29 taken 1 times.
✓ Branch 32 taken 1 times.
3 LOG_ERROR("Illegal flag detected. " << HELP_MSG);
107 1 exit(EXIT_FAILURE);
108 break;
109 }
110 }
111
112 24 return options;
113 }
114
115 24 DistanceOptions ParseDistanceOptions(int argc, char **argv) {
116 // Define an enum for each valid flag (command-line entry), which maps it from the name
117 // to an integer
118 enum class ClientOption {
119 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
120 prop,
121 DISTANCE
122 #undef FOUND_CLI_OPTION
123 };
124
125 // Define an array of options, which defines the traits pertaining to each
126 // expected command-line entry
127 static option long_options[] = {
128 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
129 {name, \
130 defaultArg == kNoDefaultArgument ? required_argument : optional_argument, \
131 0, \
132 static_cast<int>(ClientOption::prop)},
133 DISTANCE
134 #undef FOUND_CLI_OPTION
135 {0}
136 };
137
138 // Define our result, and iterator helpers
139
1/1
✓ Branch 1 taken 24 times.
24 DistanceOptions options;
140 24 int index;
141 int option;
142
143 // Iterates through the list of command-line tokens and figures out
144 // what data to assign to which field in options. Note that the
145 // FOUND_CLI_OPTION defines the conversion already between any
146 // particular parameter (as a string) to its actual type
147
2/2
✓ Branch 1 taken 103 times.
✓ Branch 2 taken 23 times.
126 while ((option = getopt_long(argc, argv, "", long_options, &index)) != -1) {
148
21/21
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 4 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 3 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 3 times.
✓ Branch 16 taken 2 times.
✓ Branch 17 taken 2 times.
✓ Branch 18 taken 7 times.
✓ Branch 19 taken 5 times.
✓ Branch 20 taken 1 times.
103 switch (option) {
149 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
150 case static_cast<int>(ClientOption::prop): \
151 ASSIGN(options, prop, converter, defaultArg) \
152 break;
153
45/45
✓ Branch 3 taken 13 times.
✓ Branch 6 taken 13 times.
✓ Branch 15 taken 9 times.
✓ Branch 18 taken 9 times.
✓ Branch 26 taken 11 times.
✓ Branch 27 taken 2 times.
✓ Branch 28 taken 8 times.
✓ Branch 29 taken 3 times.
✓ Branch 30 taken 2 times.
✓ Branch 31 taken 6 times.
✓ Branch 32 taken 4 times.
✓ Branch 33 taken 9 times.
✓ Branch 37 taken 4 times.
✓ Branch 40 taken 4 times.
✓ Branch 48 taken 8 times.
✓ Branch 51 taken 8 times.
✓ Branch 59 taken 8 times.
✓ Branch 62 taken 8 times.
✓ Branch 70 taken 9 times.
✓ Branch 73 taken 9 times.
✓ Branch 81 taken 2 times.
✓ Branch 84 taken 2 times.
✓ Branch 92 taken 2 times.
✓ Branch 95 taken 2 times.
✓ Branch 103 taken 2 times.
✓ Branch 112 taken 2 times.
✓ Branch 115 taken 2 times.
✓ Branch 121 taken 4 times.
✓ Branch 126 taken 3 times.
✓ Branch 135 taken 3 times.
✓ Branch 144 taken 3 times.
✓ Branch 147 taken 3 times.
✓ Branch 155 taken 3 times.
✓ Branch 158 taken 3 times.
✓ Branch 164 taken 7 times.
✓ Branch 166 taken 4 times.
✓ Branch 167 taken 1 times.
✓ Branch 168 taken 3 times.
✓ Branch 169 taken 1 times.
✓ Branch 170 taken 1 times.
✓ Branch 171 taken 2 times.
✓ Branch 172 taken 2 times.
✓ Branch 173 taken 3 times.
✓ Branch 177 taken 2 times.
✓ Branch 180 taken 2 times.
248 DISTANCE
154 #undef FOUND_CLI_OPTION
155 1 default:
156
9/9
✓ Branch 3 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 16 taken 1 times.
✓ Branch 20 taken 1 times.
✓ Branch 23 taken 1 times.
✓ Branch 26 taken 1 times.
✓ Branch 29 taken 1 times.
✓ Branch 32 taken 1 times.
3 LOG_ERROR("Illegal flag detected. " << HELP_MSG);
157 1 exit(EXIT_FAILURE);
158 break;
159 }
160 }
161
162 46 return options;
163 }
164
165 3 OrbitOptions ParseOrbitOptions(int argc, char **argv) {
166 // Define an enum for each valid flag (command-line entry), which maps it from the name
167 // to an integer
168 enum class ClientOption {
169 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
170 prop,
171 ORBIT
172 #undef FOUND_CLI_OPTION
173 };
174
175 // Define an array of options, which defines the traits pertaining to each
176 // expected command-line entry
177 static option long_options[] = {
178 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
179 {name, \
180 defaultArg == kNoDefaultArgument ? required_argument : optional_argument, \
181 0, \
182 static_cast<int>(ClientOption::prop)},
183 ORBIT
184 #undef FOUND_CLI_OPTION
185 {0}
186 };
187
188 // Define our result, and iterator helpers
189
1/1
✓ Branch 1 taken 3 times.
3 OrbitOptions options;
190 3 int index;
191 int option;
192
193 // Iterates through the list of command-line tokens and figures out
194 // what data to assign to which field in options. Note that the
195 // FOUND_CLI_OPTION defines the conversion already between any
196 // particular parameter (as a string) to its actual type
197
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 2 times.
9 while ((option = getopt_long(argc, argv, "", long_options, &index)) != -1) {
198
7/7
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
7 switch (option) {
199 #define FOUND_CLI_OPTION(name, type, prop, defaultVal, converter, defaultArg, ASSIGN, doc) \
200 case static_cast<int>(ClientOption::prop): \
201 ASSIGN(options, prop, converter, defaultArg) \
202 break;
203
11/11
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 16 taken 1 times.
✓ Branch 21 taken 1 times.
✓ Branch 24 taken 1 times.
✓ Branch 32 taken 1 times.
✓ Branch 35 taken 1 times.
✓ Branch 43 taken 1 times.
✓ Branch 46 taken 1 times.
✓ Branch 54 taken 1 times.
✓ Branch 57 taken 1 times.
16 ORBIT
204 #undef FOUND_CLI_OPTION
205 1 default:
206
9/9
✓ Branch 3 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 16 taken 1 times.
✓ Branch 20 taken 1 times.
✓ Branch 23 taken 1 times.
✓ Branch 26 taken 1 times.
✓ Branch 29 taken 1 times.
✓ Branch 32 taken 1 times.
3 LOG_ERROR("Illegal flag detected. " << HELP_MSG);
207 1 exit(EXIT_FAILURE);
208 break;
209 }
210 }
211
212 4 return options;
213 }
214
215 } // namespace found
216