GCC Code Coverage Report


Directory: ./
File: tmp_project/PhoenixOptionParser/src/Option.cpp
Date: 2025-03-14 12:04:36
Exec Total Coverage
Lines: 169 193 87.6%
Branches: 132 224 58.9%

Line Branch Exec Source
1 /***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5 ****************************************/
6
7 #include "phoenix_color.h"
8 #include "Option.h"
9
10 ///Default constructor of Option
11 38 Option::Option()
12
5/5
✓ Branch 2 taken 38 times.
✓ Branch 5 taken 38 times.
✓ Branch 8 taken 38 times.
✓ Branch 12 taken 38 times.
✓ Branch 15 taken 38 times.
38 :p_longName(""), p_shortName(""), p_value(""), p_isRequired(false), p_docString("")
13 {
14
1/1
✓ Branch 1 taken 38 times.
38 initialisationOption();
15 38 }
16
17 ///Default constructor of Option
18 /** @param longName : long name of the option
19 * @param shortName : long name of the option
20 * @param docString : documentation string of the Option
21 */
22 Option::Option(const PString & longName, const PString & shortName, const PString & docString)
23 :p_longName(longName), p_shortName(shortName), p_value(""), p_isRequired(false), p_docString(docString)
24 {
25 initialisationOption();
26 }
27
28 ///Constructor of Option
29 /** @param longName : long name of the option
30 * @param shortName : long name of the option
31 * @param value : value of the Option
32 * @param docString : documentation string of the Option
33 */
34 Option::Option(const PString & longName, const PString & shortName, const OptionValue & value, const PString & docString)
35 :p_longName(longName), p_shortName(shortName), p_value(value), p_isRequired(false), p_docString(docString)
36 {
37 initialisationOption();
38 }
39
40 ///Constructor of Option
41 /** @param longName : long name of the option
42 * @param shortName : long name of the option
43 * @param value : value of the Option
44 * @param isRequired : true if the option is required, false if it is optionnal
45 * @param docString : documentation string of the Option
46 */
47 176 Option::Option(const PString & longName, const PString & shortName, const OptionValue & value, bool isRequired, const PString & docString)
48
4/4
✓ Branch 2 taken 176 times.
✓ Branch 5 taken 176 times.
✓ Branch 8 taken 176 times.
✓ Branch 11 taken 176 times.
176 :p_longName(longName), p_shortName(shortName), p_value(value), p_isRequired(isRequired), p_docString(docString)
49 {
50
1/1
✓ Branch 1 taken 176 times.
176 initialisationOption();
51 176 }
52
53 ///Constructor of Option
54 /** @param longName : long name of the option
55 * @param shortName : long name of the option
56 * @param isRequired : true if the option is required, false if it is optionnal
57 * @param docString : documentation string of the Option
58 */
59 2 Option::Option(const PString & longName, const PString & shortName, bool isRequired, const PString & docString)
60
4/4
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
✓ Branch 11 taken 2 times.
2 :p_longName(longName), p_shortName(shortName), p_isRequired(isRequired), p_docString(docString)
61 {
62
1/1
✓ Branch 1 taken 2 times.
2 initialisationOption();
63 2 }
64
65 ///Copy constructor of Option
66 /** @param other : class to copy
67 */
68
4/4
✓ Branch 2 taken 397 times.
✓ Branch 5 taken 397 times.
✓ Branch 8 taken 397 times.
✓ Branch 11 taken 397 times.
397 Option::Option(const Option & other){
69
1/1
✓ Branch 1 taken 397 times.
397 copyOption(other);
70 397 }
71
72 ///Destructeur of Option
73 1020 Option::~Option(){
74
75 }
76
77 ///Definition of equal operator of Option
78 /** @param other : class to copy
79 * @return copied class
80 */
81 37 Option & Option::operator = (const Option & other){
82 37 copyOption(other);
83 37 return *this;
84 }
85
86 ///Parse the current option with the given parser
87 /** @param[out] parser : parser of the given arguments to the program
88 * @return true on success, false otherwise
89 */
90 72 bool Option::parseOption(ArgParser & parser){
91
3/3
✓ Branch 2 taken 68 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 46 times.
76 if(parsePartOption(parser, "--", p_longName)){return true;}
92
3/3
✓ Branch 2 taken 45 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 23 times.
46 else if(parsePartOption(parser, "-", p_shortName)){return true;}
93 23 return false;
94 }
95
96 ///Print a vector of value
97 /** @param vecValue : vector of value to be ploted
98 */
99 11 void printVecString(const PVecString & vecValue){
100
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if(vecValue.size() == 0lu){return;}
101 11 PVecString::const_iterator it(vecValue.begin());
102
1/1
✓ Branch 2 taken 11 times.
11 std::cout << *it;
103 11 ++it;
104
2/2
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11 times.
15 while(it != vecValue.end()){
105
2/2
✓ Branch 1 taken 4 times.
✓ Branch 5 taken 4 times.
4 std::cout << ", " << *it;
106 4 ++it;
107 }
108 }
109
110 ///Print an option
111 /** @param indentation : indentation to print the option
112 */
113 40 void Option::print(const PString & indentation) const{
114 40 OptionType::OptionType type(p_value.getType());
115 40 std::cout << indentation;
116
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 if(p_shortName != ""){
117 40 std::cout << "-" << p_shortName;
118
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
40 if(type != OptionType::NONE){
119
1/1
✓ Branch 3 taken 39 times.
39 std::cout << " " << convertOptionTypeToString(type);
120 }
121 }
122
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 if(p_longName != ""){
123
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 if(p_shortName != ""){std::cout << " , ";}
124 40 std::cout << "--" << p_longName;
125
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
40 if(type != OptionType::NONE){
126
1/1
✓ Branch 3 taken 39 times.
39 std::cout << "=" << convertOptionTypeToString(type);
127 }
128 }
129
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 if(p_docString != ""){
130 40 std::cout << " : " << p_docString;
131 }
132 40 std::cout << std::endl;
133 40 const PVecString & vecDefaultValue = p_value.getDefaultValue();
134
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 31 times.
40 if(vecDefaultValue.size()){
135 9 std::cout << indentation << "\tDefault value : '";
136 9 printVecString(vecDefaultValue);
137 9 std::cout << "'" << std::endl;
138 }
139 40 const PVecString & vecPossibleValue = p_value.getPossibleValue();
140
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 38 times.
40 if(vecPossibleValue.size()){
141 2 std::cout << indentation << "\tPossible values : ";
142 2 printVecString(vecPossibleValue);
143 2 std::cout << std::endl;
144 }
145
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 14 times.
40 if(p_isRequired){std::cout << indentation << "\tThis argument has to be set" << std::endl;}
146 14 else{std::cout << indentation << "\tThis argument is optional" << std::endl;}
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if(p_isAllowEmpty){std::cout << indentation << "\tThis argument can have an empty value" << std::endl;}
148 40 else{std::cout << indentation << "\tThis argument cannot have an empty value" << std::endl;}
149 40 }
150
151 ///Set the long name of the option
152 /** @param longName : long name of the option
153 */
154 1 void Option::setLongName(const PString & longName){p_longName = longName;}
155
156 ///Set the short name of the option
157 /** @param shortName : short name of the option
158 */
159 1 void Option::setShortName(const PString & shortName){p_shortName = shortName;}
160
161 ///Set the value of the option
162 /** @param value : value name of the option
163 */
164 1 void Option::setValue(const OptionValue & value){p_value = value;}
165
166 ///Set if the option is required
167 /** @param isRequired : true if the Option is required, false if it is optionnal
168 */
169 1 void Option::setIsRequired(bool isRequired){p_isRequired = isRequired;}
170
171 ///Set the documentation string of the Option
172 /** @param docString : documentation string of the Option
173 */
174 1 void Option::setDocString(const PString & docString){p_docString = docString;}
175
176 ///Say if the Option has been parsed or not
177 /** @param isParsed : true if the Option has been parsed, false if not
178 */
179 1 void Option::setIsParsed(bool isParsed){p_isParsed = isParsed;}
180
181 ///Say if the option can be empty or not
182 /** @param isAllowEmpty : true if the option can be empty, false otherwise
183 */
184 132 void Option::setIsAllowEmpty(bool isAllowEmpty){p_isAllowEmpty = isAllowEmpty;}
185
186 ///Get the long name of the Option
187 /** @return long name of the Option
188 */
189 166 const PString & Option::getLongName() const{return p_longName;}
190
191 ///Get the long name of the Option
192 /** @return long name of the Option
193 */
194 1 PString & Option::getLongName(){return p_longName;}
195
196 ///Get the short name of the Option
197 /** @return short name of the Option
198 */
199 84 const PString & Option::getShortName() const{return p_shortName;}
200
201 ///Get the short name of the Option
202 /** @return short name of the Option
203 */
204 1 PString & Option::getShortName(){return p_shortName;}
205
206 ///Get the value of the Option
207 /** @return value of the Option
208 */
209 3 const OptionValue & Option::getValue() const{return p_value;}
210
211 ///Get the value of the Option
212 /** @return value of the Option
213 */
214 38 OptionValue & Option::getValue(){return p_value;}
215
216 ///Get if the option is required
217 /** @return true if the Option is required, false if it is optionnal
218 */
219 3 bool Option::isRequired() const{return p_isRequired;}
220
221 ///Get if the option is required
222 /** @return true if the Option is required, false if it is optionnal
223 */
224 9 bool & Option::isRequired(){return p_isRequired;}
225
226 ///Get if the option value can be empty
227 /** @return true if the option value can be empty, false otherwise
228 */
229 3 bool Option::isAllowEmpty() const{return p_isAllowEmpty;}
230
231 ///Get if the option value can be empty
232 /** @return true if the option value can be empty, false otherwise
233 */
234 1 bool & Option::isAllowEmpty(){return p_isAllowEmpty;}
235
236 ///Get the documentation string of the Option
237 /** @return documentation string of the Option
238 */
239 3 const PString & Option::getDocString() const{return p_docString;}
240
241 ///Get the documentation string of the Option
242 /** @return documentation string of the Option
243 */
244 1 PString & Option::getDocString(){return p_docString;}
245
246 ///Say if the Option has been parsed or not
247 /** @return true if the Option has been parsed, false if not
248 */
249 5 bool Option::isParsed() const{return p_isParsed;}
250
251 ///Say if the Option has been parsed or not
252 /** @return true if the Option has been parsed, false if not
253 */
254 74 bool & Option::isParsed(){return p_isParsed;}
255
256 ///Check the argument of the parser
257 /** @return true if the arguments is required and is set, false otherwise
258 */
259 54 bool Option::checkArgument() const{
260
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 26 times.
54 if(p_isRequired){
261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if(!p_isParsed){
262 OptionType::OptionType type(p_value.getType());
263 std::cerr << termRed() << "Missing arguement ";
264 if(p_longName != ""){
265 std::cerr << "--" << p_longName;
266 if(type != OptionType::NONE){
267 std::cout << "=" << convertOptionTypeToString(type);
268 }
269 }
270 if(p_shortName != ""){
271 if(p_longName != ""){std::cerr << " , ";}
272 std::cerr << "-" << p_shortName;
273 if(type != OptionType::NONE){
274 std::cout << " " << convertOptionTypeToString(type);
275 }
276 }
277 std::cerr << termDefault() << std::endl;
278 }
279 28 return p_isParsed;
280 26 }else{return true;}
281 }
282
283 ///Get the possible options for the bash completion
284 /** @param[out] possibleOption : possible options for the bash completion
285 * @param cursorOption : option of the cursor which is currently completed
286 */
287 29 void Option::getPossibleOption(PString & possibleOption, const PString & cursorOption) const{
288
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 24 times.
29 if(p_isParsed){return;}
289
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 if(p_longName != ""){
290
2/2
✓ Branch 1 taken 24 times.
✓ Branch 4 taken 24 times.
24 PString longOption("--" + p_longName);
291
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 18 times.
24 if(cursorOption == ""){
292
2/2
✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
6 possibleOption += longOption + " ";
293 }else{
294
3/3
✓ Branch 1 taken 18 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 2 times.
18 if(longOption.isSameBegining(cursorOption)){
295
2/2
✓ Branch 1 taken 16 times.
✓ Branch 4 taken 16 times.
16 possibleOption += longOption + " ";
296 }
297 }
298 24 }
299
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 if(p_shortName != ""){
300
2/2
✓ Branch 1 taken 24 times.
✓ Branch 4 taken 24 times.
24 PString shortOption("-" + p_shortName);
301
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 18 times.
24 if(cursorOption == ""){
302
2/2
✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
6 possibleOption += shortOption + " ";
303 }else{
304
3/3
✓ Branch 1 taken 18 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 14 times.
18 if(shortOption.isSameBegining(cursorOption)){
305
2/2
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
4 possibleOption += shortOption + " ";
306 }
307 }
308 24 }
309 }
310
311 ///Complete the possible values of the Option
312 /** @param[out] possibleValue : possible value of the option
313 * @param cursorOption : option of the cursor which is currently completed
314 */
315 11 void Option::getPossibleValue(PString & possibleValue, const PString & cursorOption) const{
316 11 p_value.bashCompletionValue(possibleValue, cursorOption);
317 11 }
318
319 ///Copy function of Option
320 /** @param other : class to copy
321 */
322 434 void Option::copyOption(const Option & other){
323 434 p_longName = other.p_longName;
324 434 p_shortName = other.p_shortName;
325 434 p_value = other.p_value;
326 434 p_isRequired = other.p_isRequired;
327 434 p_docString = other.p_docString;
328 434 p_isParsed = other.p_isParsed;
329 434 p_firstPartParsedOption = other.p_firstPartParsedOption;
330 434 p_isAllowEmpty = other.p_isAllowEmpty;
331 434 }
332
333 ///Initialisation function of the class Option
334 216 void Option::initialisationOption(){
335 216 p_isParsed = false;
336 216 p_firstPartParsedOption = "";
337 216 p_isAllowEmpty = false;
338 216 }
339
340 ///Parse the given option with the parser
341 /** @param[out] parser : parser to be used
342 * @param prefix : option prefix (- or -- or nothing)
343 * @param optionName : name of hte option to be parsed
344 * @return true on success, false otherwise
345 */
346 118 bool Option::parsePartOption(ArgParser & parser, const PString & prefix, const PString & optionName){
347
2/3
✓ Branch 1 taken 118 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 118 times.
118 if(parser.isEndOfOption()){return true;}
348
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 118 times.
118 if(optionName == ""){return false;}
349
1/1
✓ Branch 1 taken 118 times.
118 PString & currentOption = parser.getCurrentOption();
350
2/2
✓ Branch 1 taken 118 times.
✓ Branch 4 taken 118 times.
118 PString longOption(prefix + optionName);
351 118 size_t sizeLongOption(longOption.size());
352
1/1
✓ Branch 1 taken 118 times.
118 OptionType::OptionType optionType = p_value.getType();
353
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 84 times.
118 if(currentOption == longOption){
354
1/1
✓ Branch 1 taken 34 times.
34 checkAlreadyParsed(longOption);
355 34 p_isParsed = true;
356
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 32 times.
34 if(optionType == OptionType::NONE){ //No value expected
357
1/1
✓ Branch 1 taken 2 times.
2 parser.getNextOption();
358 2 return true; //Option found
359 }
360 32 bool valueOk(true), isInitialised(false);
361
1/1
✓ Branch 1 taken 32 times.
32 parser.getNextOption();
362
7/7
✓ Branch 1 taken 66 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 34 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 34 times.
✓ Branch 8 taken 32 times.
66 while(!parser.isEndOfOption() && valueOk){
363
1/1
✓ Branch 1 taken 34 times.
34 PString & currentOption = parser.getCurrentOption();
364
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 33 times.
34 if(currentOption == ""){
365
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(optionType == OptionType::STRING){
366
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 p_value.addValue("");
367
1/1
✓ Branch 1 taken 1 times.
1 parser.getNextOption();
368 1 valueOk = true;
369 1 isInitialised = true;
370 }else{
371 throw std::runtime_error("Option::parsePartOption : pass empty value to option '" + longOption + "' which does not expect STRING");
372 }
373 }else{
374
3/3
✓ Branch 1 taken 33 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 28 times.
33 if(currentOption[0] == '-'){
375 5 valueOk = false;
376 }else{
377
1/1
✓ Branch 1 taken 28 times.
28 p_value.addValue(currentOption);
378
1/1
✓ Branch 1 taken 28 times.
28 parser.getNextOption();
379 28 valueOk = true;
380 28 isInitialised = true;
381 }
382 }
383 }
384
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
32 if(!isInitialised && !p_isAllowEmpty){
385
3/3
✓ Branch 2 taken 5 times.
✓ Branch 5 taken 5 times.
✓ Branch 8 taken 5 times.
5 throw std::runtime_error("Option::parsePartOption : expect value after option '" + longOption + "'");
386 }
387
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 return isInitialised || p_isAllowEmpty;
388
3/3
✓ Branch 1 taken 84 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 69 times.
84 }else if(currentOption.isSameBegining(longOption)){
389
2/3
✓ Branch 1 taken 15 times.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
15 if(currentOption[sizeLongOption] == '='){
390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if(optionType == OptionType::NONE){ //No value expected
391 throw std::runtime_error("Option::parsePartOption : the option '"+currentOption+"' does not have value");
392 }
393
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
15 if(currentOption.size() == sizeLongOption + 1lu){
394 p_firstPartParsedOption = longOption + "=";
395 throw std::runtime_error("Option::parsePartOption : problem with the option '"+currentOption+"' because it ends with a '=' and not a value");
396 //Ici il faut un mode qui renvoie quand même les valeurs possibles quand on a --option=...
397 }
398
1/1
✓ Branch 1 taken 15 times.
15 checkAlreadyParsed(longOption);
399
2/2
✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
15 PString value(currentOption.substr(sizeLongOption + 1lu));
400
1/1
✓ Branch 1 taken 15 times.
15 p_value.addValue(value);
401 15 p_isParsed = true;
402
1/1
✓ Branch 1 taken 15 times.
15 parser.getNextOption();
403 15 return true;
404 15 }else{
405 return false; //It is an option with a longer name
406 }
407 }
408 69 return false;
409 118 }
410
411 ///Check if the Option has been already parsed
412 /** @param longOption : used option
413 */
414 49 void Option::checkAlreadyParsed(const PString & longOption){
415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
49 if(p_isParsed){ //The option has already been parsed, there is a mistake
416 throw std::runtime_error("Option::checkAlreadyParsed : option '" + longOption + "' already exists");
417 }
418 49 }
419
420
421
422
423