Directory: | ./ |
---|---|
File: | src/OptionParser.cpp |
Date: | 2024-07-27 10:53:27 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 215 | 227 | 94.7% |
Branches: | 220 | 269 | 81.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /*************************************** | ||
2 | Auteur : Pierre Aubert | ||
3 | Mail : pierre.aubert@lapp.in2p3.fr | ||
4 | Licence : CeCILL-C | ||
5 | ****************************************/ | ||
6 | |||
7 | #include "string_utils.h" | ||
8 | #include "OptionParser.h" | ||
9 | |||
10 | using namespace std; | ||
11 | |||
12 | ///Default constructeur of OptionParser | ||
13 | /** @param enableHelpOption : True to enable automatically the printing of the help option when the program is called with --help or -h | ||
14 | * @param programVersion : version of the program to be printed on --version or -v options | ||
15 | */ | ||
16 | 55 | OptionParser::OptionParser(bool enableHelpOption, const std::string & programVersion) | |
17 |
1/1✓ Branch 4 taken 55 times.
|
55 | :p_enableHelpOption(enableHelpOption), p_programVersion(programVersion) |
18 | { | ||
19 |
1/1✓ Branch 1 taken 55 times.
|
55 | initialisationOptionParser(); |
20 | 55 | } | |
21 | |||
22 | ///Copy constructor of OptionParser | ||
23 | /** @param other : class to copy | ||
24 | */ | ||
25 | 2 | OptionParser::OptionParser(const OptionParser & other){ | |
26 |
1/1✓ Branch 1 taken 2 times.
|
2 | copyOptionParser(other); |
27 | 2 | } | |
28 | |||
29 | ///Destructeur of OptionParser | ||
30 | 56 | OptionParser::~OptionParser(){ | |
31 | |||
32 | } | ||
33 | |||
34 | ///Definition of equal operator of OptionParser | ||
35 | /** @param other : class to copy | ||
36 | * @return copied class | ||
37 | */ | ||
38 | 2 | OptionParser & OptionParser::operator = (const OptionParser & other){ | |
39 | 2 | copyOptionParser(other); | |
40 | 2 | return *this; | |
41 | } | ||
42 | |||
43 | ///Set the example usage of the program | ||
44 | /** @param example : example of usage | ||
45 | */ | ||
46 | 13 | void OptionParser::setExampleLongOption(const std::string & example){p_exempleLongOption = example;} | |
47 | |||
48 | ///Set the example usage of the program | ||
49 | /** @param example : example of usage | ||
50 | */ | ||
51 | 13 | void OptionParser::setExampleShortOption(const std::string & example){p_exempleShortOption = example;} | |
52 | |||
53 | ///Add a mode in the option | ||
54 | /** @param modeName : name of the new mode to be added | ||
55 | */ | ||
56 | 64 | void OptionParser::addMode(const std::string & modeName){ | |
57 |
1/1✓ Branch 1 taken 64 times.
|
64 | OptionMode mode(modeName); |
58 |
1/1✓ Branch 1 taken 64 times.
|
64 | mode.setEnableHelpOption(p_enableHelpOption); |
59 |
1/1✓ Branch 1 taken 64 times.
|
64 | mode.setProgramVersion(p_programVersion); |
60 |
1/1✓ Branch 1 taken 64 times.
|
64 | p_vecMode.push_back(mode); |
61 | 64 | p_currentMode = p_vecMode.size() - 1lu; | |
62 | 64 | } | |
63 | |||
64 | ///Close the current mode and go back to be default one | ||
65 | 64 | void OptionParser::closeMode(){ | |
66 | 64 | p_currentMode = 0lu; | |
67 | 64 | } | |
68 | |||
69 | ///Add an option in the OptionParser | ||
70 | /** @param longOption : long option (start with --) as --version | ||
71 | * @param shortOption : short option (start with -) as -v | ||
72 | * @param optionType : type of the value to be parsed (INT, BOOL_ CHAR, FLOAT, STRING, FILENAME, DIRECTORY, etc) | ||
73 | * @param isRequired : true if the option is required, false if it is optionnal | ||
74 | * @param docString : documentation string of the option | ||
75 | */ | ||
76 | 121 | void OptionParser::addOption(const std::string & longOption, const std::string & shortOption, OptionType::OptionType optionType, | |
77 | bool isRequired, const std::string & docString) | ||
78 | { | ||
79 |
1/1✓ Branch 1 taken 121 times.
|
121 | OptionValue value; |
80 |
1/1✓ Branch 1 taken 121 times.
|
121 | value.setType(optionType); |
81 |
1/1✓ Branch 1 taken 121 times.
|
121 | Option option(longOption, shortOption, value, isRequired, docString); |
82 |
1/1✓ Branch 1 taken 121 times.
|
121 | option.setIsAllowEmpty(false); |
83 |
1/1✓ Branch 2 taken 121 times.
|
121 | p_vecMode[p_currentMode].addOption(option); |
84 | 121 | } | |
85 | |||
86 | ///Add an option in the OptionParser | ||
87 | /** @param longOption : long option (start with --) as --version | ||
88 | * @param shortOption : short option (start with -) as -v | ||
89 | * @param optionType : type of the value to be parsed (INT, BOOL_ CHAR, FLOAT, STRING, FILENAME, DIRECTORY, etc) | ||
90 | * @param isRequired : true if the option is required, false if it is optionnal | ||
91 | * @param isAllowEmpty : the given value can be empty | ||
92 | * @param docString : documentation string of the option | ||
93 | */ | ||
94 | 2 | void OptionParser::addOption(const std::string & longOption, const std::string & shortOption, OptionType::OptionType optionType, | |
95 | bool isRequired, bool isAllowEmpty, const std::string & docString) | ||
96 | { | ||
97 |
1/1✓ Branch 1 taken 2 times.
|
2 | OptionValue value; |
98 |
1/1✓ Branch 1 taken 2 times.
|
2 | value.setType(optionType); |
99 |
1/1✓ Branch 1 taken 2 times.
|
2 | Option option(longOption, shortOption, value, isRequired, docString); |
100 |
1/1✓ Branch 1 taken 2 times.
|
2 | option.setIsAllowEmpty(isAllowEmpty); |
101 |
1/1✓ Branch 2 taken 2 times.
|
2 | p_vecMode[p_currentMode].addOption(option); |
102 | 2 | } | |
103 | |||
104 | ///Print all the options | ||
105 | 9 | void OptionParser::print() const{ | |
106 |
7/8✓ Branch 1 taken 9 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 7 times.
✓ Branch 11 taken 2 times.
|
9 | if(p_exempleLongOption != "" || p_exempleShortOption != ""){ |
107 |
2/2✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
|
7 | cout << "Usage :" << endl; |
108 |
5/6✓ Branch 1 taken 7 times.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 7 times.
✓ Branch 9 taken 7 times.
✓ Branch 12 taken 7 times.
|
7 | if(p_exempleLongOption != ""){cout << "\t" << p_exempleLongOption << endl;} |
109 |
5/6✓ Branch 1 taken 7 times.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 7 times.
✓ Branch 9 taken 7 times.
✓ Branch 12 taken 7 times.
|
7 | if(p_exempleShortOption != ""){cout << "\t" << p_exempleShortOption << endl;} |
110 | } | ||
111 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
|
9 | cout << "Parameters :" << endl; |
112 | 9 | VecMode::const_iterator it(p_vecMode.begin()); | |
113 |
1/1✓ Branch 2 taken 9 times.
|
9 | it->print(); |
114 | 9 | ++it; | |
115 |
2/2✓ Branch 2 taken 4 times.
✓ Branch 3 taken 9 times.
|
13 | while(it != p_vecMode.end()){ |
116 |
1/1✓ Branch 2 taken 4 times.
|
4 | it->print(); |
117 | 4 | ++it; | |
118 | } | ||
119 | 9 | } | |
120 | |||
121 | ///Parse the arguments passed to the program | ||
122 | /** @param argc : number of parameters passed to the program | ||
123 | * @param argv : list of arguments passed to the program | ||
124 | */ | ||
125 | 53 | void OptionParser::parseArgument(int argc, char** argv){ | |
126 |
1/1✓ Branch 1 taken 53 times.
|
53 | ArgParser parser(argc, argv); |
127 |
3/3✓ Branch 1 taken 53 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 31 times.
|
53 | if(parser.isBashCompletionMode()){ |
128 |
0/1✗ Branch 1 not taken.
|
22 | parseArgumentBashCompletion(parser); |
129 | }else{ | ||
130 |
1/1✓ Branch 1 taken 24 times.
|
31 | parseArgumentNormalUse(parser); |
131 | } | ||
132 | 24 | } | |
133 | |||
134 | ///Get default mode | ||
135 | /** @return default mode | ||
136 | */ | ||
137 | 6 | const OptionMode & OptionParser::getDefaultMode() const{ | |
138 | 6 | return p_vecMode[0lu]; | |
139 | } | ||
140 | |||
141 | ///Get default mode | ||
142 | /** @return default mode | ||
143 | */ | ||
144 | 15 | OptionMode & OptionParser::getDefaultMode(){ | |
145 | 15 | return p_vecMode[0lu]; | |
146 | } | ||
147 | |||
148 | ///Get mode by name | ||
149 | /** @param name : name of the mode to be returned | ||
150 | * @return corresponding mode if the mode exists or the default mode otherwise | ||
151 | */ | ||
152 | 4 | const OptionMode & OptionParser::getMode(const std::string & name) const{ | |
153 |
2/2✓ Branch 4 taken 6 times.
✓ Branch 5 taken 2 times.
|
8 | for(VecMode::const_iterator it(p_vecMode.begin()); it != p_vecMode.end(); ++it){ |
154 |
3/3✓ Branch 2 taken 6 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 4 times.
|
6 | if(it->getName() == name){ |
155 | 2 | return *it; | |
156 | } | ||
157 | } | ||
158 | 2 | return getDefaultMode(); | |
159 | } | ||
160 | |||
161 | ///Get mode by name | ||
162 | /** @param name : name of the mode to be returned | ||
163 | * @return corresponding mode if the mode exists or the default mode otherwise | ||
164 | */ | ||
165 | 38 | OptionMode & OptionParser::getMode(const std::string & name){ | |
166 |
2/2✓ Branch 4 taken 89 times.
✓ Branch 5 taken 2 times.
|
91 | for(VecMode::iterator it(p_vecMode.begin()); it != p_vecMode.end(); ++it){ |
167 |
3/3✓ Branch 2 taken 89 times.
✓ Branch 5 taken 36 times.
✓ Branch 6 taken 53 times.
|
89 | if(it->getName() == name){ |
168 | 36 | return *it; | |
169 | } | ||
170 | } | ||
171 | 2 | return getDefaultMode(); | |
172 | } | ||
173 | |||
174 | ///Check if the given mode name does exist | ||
175 | /** @param name : name of the mode | ||
176 | * @return true if the given mode name does exist, false otherwise | ||
177 | */ | ||
178 | 35 | bool OptionParser::isModeExist(const std::string & name) const{ | |
179 | 35 | bool isSearch(true); | |
180 | 35 | VecMode::const_iterator it(p_vecMode.begin()); | |
181 |
6/6✓ Branch 0 taken 83 times.
✓ Branch 1 taken 16 times.
✓ Branch 4 taken 64 times.
✓ Branch 5 taken 19 times.
✓ Branch 6 taken 64 times.
✓ Branch 7 taken 35 times.
|
99 | while(isSearch && it != p_vecMode.end()){ |
182 |
1/1✓ Branch 2 taken 64 times.
|
64 | isSearch &= it->getName() != name; |
183 | 64 | ++it; | |
184 | } | ||
185 | 35 | return !isSearch; | |
186 | } | ||
187 | |||
188 | ///Copy function of OptionParser | ||
189 | /** @param other : class to copy | ||
190 | */ | ||
191 | 4 | void OptionParser::copyOptionParser(const OptionParser & other){ | |
192 | 4 | p_vecMode = other.p_vecMode; | |
193 | 4 | p_currentMode = other.p_currentMode; | |
194 | 4 | p_exempleShortOption = other.p_exempleShortOption; | |
195 | 4 | p_exempleLongOption = other.p_exempleLongOption; | |
196 | 4 | p_programVersion = other.p_programVersion; | |
197 | 4 | p_enableHelpOption = other.p_enableHelpOption; | |
198 | 4 | } | |
199 | |||
200 | ///Initialisation function of the class OptionParser | ||
201 | 55 | void OptionParser::initialisationOptionParser(){ | |
202 | 55 | p_currentMode = 0lu; | |
203 | 55 | p_currentParserMode = NULL; | |
204 |
2/2✓ Branch 2 taken 55 times.
✓ Branch 5 taken 55 times.
|
110 | OptionMode defaultMode; |
205 |
1/1✓ Branch 1 taken 55 times.
|
55 | p_vecMode.push_back(defaultMode); |
206 | 55 | } | |
207 | |||
208 | ///Classical argument parsing mode | ||
209 | /** @param parser : parser to be used | ||
210 | */ | ||
211 | 31 | void OptionParser::parseArgumentNormalUse(ArgParser & parser){ | |
212 | 31 | p_currentParserMode = &p_vecMode.front(); | |
213 |
2/2✓ Branch 1 taken 36 times.
✓ Branch 2 taken 24 times.
|
60 | while(!parser.isEndOfOption()){ |
214 |
1/2✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
|
36 | if(p_enableHelpOption){ |
215 |
5/6✓ Branch 2 taken 35 times.
✓ Branch 3 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 35 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 35 times.
|
36 | if(parser.getCurrentOption() == "--help" || parser.getCurrentOption() == "-h"){ |
216 | 1 | print(); | |
217 | 1 | exit(0); | |
218 | } | ||
219 | } | ||
220 |
1/2✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
|
35 | if(p_programVersion != ""){ |
221 |
3/6✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 35 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 35 times.
|
35 | if(parser.getCurrentOption() == "--version" || parser.getCurrentOption() == "-v"){ |
222 | ✗ | cout << "Program version : " << p_programVersion << endl; | |
223 | ✗ | exit(0); | |
224 | } | ||
225 | } | ||
226 | 35 | OptionMode & currentMode = getParserMode(parser); | |
227 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
|
35 | if(!currentMode.parseOption(parser)){ |
228 | ✗ | std::string modeName(currentMode.getName()); | |
229 | ✗ | std::string modeError(""); | |
230 | ✗ | if(modeName != ""){ | |
231 | ✗ | modeError = " in mode '"+modeName+"' "; | |
232 | } | ||
233 | ✗ | throw std::runtime_error("OptionParser::parseArgument : unknown option '"+parser.getCurrentOption()+"'" + modeError); | |
234 | } | ||
235 | } | ||
236 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
|
24 | if(!checkArgument()){ |
237 | ✗ | throw std::runtime_error("OptionParser::parseArgument : missing argument"); | |
238 | } | ||
239 | 24 | } | |
240 | |||
241 | ///Bash completion argument parsing mode | ||
242 | /** @param parser : parser to be used | ||
243 | */ | ||
244 | 22 | void OptionParser::parseArgumentBashCompletion(ArgParser & parser){ | |
245 | //First step, we parse normally the existing arguments | ||
246 |
2/2✓ Branch 1 taken 22 times.
✓ Branch 4 taken 22 times.
|
22 | std::string cursorOption(parser.getCursorOption()); |
247 |
2/2✓ Branch 1 taken 22 times.
✓ Branch 4 taken 22 times.
|
22 | std::string prevCursorOption(parser.getPrevCursorOption()); |
248 | 22 | Option * partialOption = NULL; | |
249 |
3/3✓ Branch 1 taken 45 times.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 22 times.
|
45 | while(!parser.isEndOfOption()){ //We loop to find the option which has not been parsed well |
250 | 23 | bool isSearch(true); | |
251 | 23 | VecMode::iterator itMode = p_vecMode.begin(); | |
252 |
9/9✓ Branch 1 taken 68 times.
✓ Branch 3 taken 54 times.
✓ Branch 4 taken 14 times.
✓ Branch 7 taken 48 times.
✓ Branch 8 taken 6 times.
✓ Branch 9 taken 45 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 45 times.
✓ Branch 12 taken 23 times.
|
68 | while(!parser.isEndOfOption() && itMode != p_vecMode.end() && isSearch){ |
253 |
1/1✓ Branch 2 taken 45 times.
|
45 | isSearch = !itMode->parseOption(parser, partialOption); |
254 | 45 | ++itMode; | |
255 | } | ||
256 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 12 times.
|
23 | if(isSearch){ //If no option matches, we go to the next argument |
257 |
1/1✓ Branch 1 taken 11 times.
|
11 | parser.getNextOption(); |
258 | } | ||
259 | } | ||
260 | //Complete the ongoing option (filename, directory, enum value, etc) | ||
261 | // if(partialOption != NULL){ //The option name has no ambiguity but we expect a value | ||
262 | // std::string possibleValue(""); | ||
263 | // partialOption->getPossibleValue(possibleValue, cursorOption); | ||
264 | // cout << possibleValue << endl; | ||
265 | // }else{ | ||
266 | //Let's get the mode which is currently parsed | ||
267 | //If all the options are fine, we have to show the remaning options. That's the following | ||
268 |
1/1✓ Branch 2 taken 22 times.
|
22 | std::string possibleValue(""); |
269 |
3/3✓ Branch 1 taken 22 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 14 times.
|
22 | if(completeOptionValue(possibleValue, cursorOption, prevCursorOption)){ |
270 | // saveFileContent("listPossibleValues.txt", possibleValue); | ||
271 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
|
8 | std::cout << possibleValue << std::endl; |
272 | }else{ | ||
273 | //Then, get the remaning arguments (not parsed yet) | ||
274 |
1/1✓ Branch 2 taken 14 times.
|
14 | std::string possibleOption(""); |
275 |
1/1✓ Branch 1 taken 14 times.
|
14 | getPossibleOption(possibleOption, cursorOption); |
276 |
1/1✓ Branch 1 taken 14 times.
|
14 | getPossibleOtherOption(possibleOption, cursorOption); |
277 | |||
278 | // saveFileContent("listPossibleOption.txt", possibleOption); | ||
279 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 4 taken 14 times.
|
14 | std::cout << possibleOption << std::endl; |
280 | 14 | } | |
281 | // } | ||
282 | 22 | exit(0); | |
283 | // La marche a suivre est assez simple | ||
284 | // On renvoie une ligne par argument possible | ||
285 | // Si il y en a qu'une seule, elle sera ajouté à la fin de la ligne de commande | ||
286 | // DONE : mettre en place un méchanisme pour générer le bash qui appellera le programme différemment | ||
287 | } | ||
288 | |||
289 | ///Check the argument of the parser | ||
290 | /** @return true if all the required arguments are set, false otherwise | ||
291 | */ | ||
292 | 24 | bool OptionParser::checkArgument() const{ | |
293 | 24 | bool isArgOk(true); | |
294 | 24 | VecMode::const_iterator it(p_vecMode.begin()); | |
295 |
5/6✓ Branch 2 taken 44 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 44 times.
✓ Branch 7 taken 24 times.
|
68 | while(it != p_vecMode.end() && isArgOk){ |
296 |
1/1✓ Branch 2 taken 44 times.
|
44 | isArgOk = it->checkArgument(); |
297 | 44 | ++it; | |
298 | } | ||
299 | 24 | return isArgOk; | |
300 | } | ||
301 | |||
302 | ///Get a mode if it exist | ||
303 | /** @param parser : parser to be used | ||
304 | * @return corresponding mode | ||
305 | */ | ||
306 | 35 | OptionMode & OptionParser::getParserMode(ArgParser & parser){ | |
307 |
2/2✓ Branch 1 taken 35 times.
✓ Branch 4 taken 35 times.
|
35 | std::string currentOption(parser.getCurrentOption()); |
308 |
3/3✓ Branch 1 taken 35 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 19 times.
|
35 | if(isModeExist(currentOption)){ |
309 |
1/1✓ Branch 1 taken 16 times.
|
16 | OptionMode & mode = getMode(currentOption); |
310 | 16 | p_currentParserMode = &mode; | |
311 |
1/1✓ Branch 1 taken 16 times.
|
16 | parser.getNextOption(); |
312 | 16 | return mode; | |
313 | }else{ | ||
314 | 19 | return *p_currentParserMode; | |
315 | } | ||
316 | 35 | } | |
317 | |||
318 | ///Get the currently parsed OptionMode | ||
319 | /** @return pointer to the currently parsed OptionMode, it there is one, or NULL is there is not | ||
320 | */ | ||
321 | 9 | const OptionMode * OptionParser::getCurrentlyParsedMode() const{ | |
322 | 9 | const OptionMode * mode = NULL; | |
323 | 9 | VecMode::const_iterator it(p_vecMode.begin()); | |
324 |
6/6✓ Branch 2 taken 27 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 9 times.
|
29 | while(it != p_vecMode.end() && mode == NULL){ |
325 |
9/9✓ Branch 2 taken 20 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 16 times.
✓ Branch 11 taken 16 times.
✓ Branch 13 taken 8 times.
✓ Branch 14 taken 8 times.
✓ Branch 15 taken 8 times.
✓ Branch 16 taken 12 times.
|
20 | if(it->isCurrentlyParsed() && it->getName() != ""){ |
326 | 8 | mode = &(*it); | |
327 | } | ||
328 | 20 | ++it; | |
329 | } | ||
330 | 9 | return mode; | |
331 | } | ||
332 | |||
333 | ///Complete the possible value of an option (FILENAME, DIRECTORY, FILE_OR_DIR) | ||
334 | /** @param[out] possibleValue : possible value | ||
335 | * @param cursorOption : option of the cursor which is currently completed | ||
336 | * @param prevCursorOption : previous option of the cursor | ||
337 | */ | ||
338 | 22 | bool OptionParser::completeOptionValue(std::string & possibleValue, const std::string & cursorOption, const std::string & prevCursorOption) const{ | |
339 | // std::cerr << "OptionParser::completeOptionValue : cursorOption = '"<<cursorOption<<"', prevCursorOption = '"<<prevCursorOption<<"'" << std::endl; | ||
340 |
1/1✓ Branch 2 taken 22 times.
|
22 | std::string valueToBeCompleted(""); |
341 | //Check is the cursor option starts with a long option (--option=value) because the value can be completed | ||
342 |
1/1✓ Branch 1 taken 22 times.
|
22 | const Option * op = getLongOptionValue(valueToBeCompleted, cursorOption); |
343 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | if(op == NULL){ //Check is the previous option corresponds to an existing option, to complete the value given by the current option |
344 |
1/1✓ Branch 1 taken 22 times.
|
22 | op = getSplitOptionValue(valueToBeCompleted, cursorOption, prevCursorOption); |
345 | } | ||
346 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 14 times.
|
22 | if(op != NULL){ |
347 |
1/1✓ Branch 1 taken 8 times.
|
8 | op->getPossibleValue(possibleValue, valueToBeCompleted); |
348 | // std::cerr << "OptionParser::completeOptionValue : possibleValue = '"<<possibleValue<<"'" << std::endl; | ||
349 | 8 | return true; | |
350 | } | ||
351 | 14 | return false; | |
352 | 22 | } | |
353 | |||
354 | ///Get the long option value to be completed | ||
355 | /** @param[out] valueToBeCompleted : base of the value to be completed | ||
356 | * @param cursorOption : option of the cursor which is currently completed | ||
357 | * @return pointer to the Option to be completed or NULL if there is not | ||
358 | */ | ||
359 | 22 | const Option * OptionParser::getLongOptionValue(std::string & valueToBeCompleted, const std::string & cursorOption) const{ | |
360 |
2/2✓ Branch 1 taken 7 times.
✓ Branch 2 taken 15 times.
|
22 | if(cursorOption == ""){return NULL;} |
361 | 15 | const Option * op = NULL; | |
362 | 15 | VecMode::const_iterator itMode(p_vecMode.begin()); | |
363 |
5/6✓ Branch 2 taken 39 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 39 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39 times.
✓ Branch 7 taken 15 times.
|
54 | while(itMode != p_vecMode.end() && op == NULL){ |
364 |
3/3✓ Branch 2 taken 39 times.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 12 times.
|
39 | if(itMode->isCurrentlyParsed()){ |
365 |
1/1✓ Branch 2 taken 27 times.
|
27 | const VecOption & vecOp = itMode->getVecOption(); |
366 | 27 | VecOption::const_iterator itOp(vecOp.begin()); | |
367 |
5/6✓ Branch 2 taken 39 times.
✓ Branch 3 taken 27 times.
✓ Branch 4 taken 39 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39 times.
✓ Branch 7 taken 27 times.
|
66 | while(itOp != vecOp.end() && op == NULL){ |
368 |
3/3✓ Branch 2 taken 39 times.
✓ Branch 5 taken 39 times.
✓ Branch 8 taken 39 times.
|
39 | std::string fullOp("--" + itOp->getLongName() + "="); |
369 |
2/3✓ Branch 1 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39 times.
|
39 | if(isSameBegining(cursorOption, fullOp)){ |
370 | ✗ | op = &(*itOp); | |
371 | ✗ | valueToBeCompleted = cursorOption.substr(fullOp.size()); | |
372 | } | ||
373 | 39 | ++itOp; | |
374 | 39 | } | |
375 | } | ||
376 | 39 | ++itMode; | |
377 | } | ||
378 | 15 | return op; | |
379 | } | ||
380 | |||
381 | ///Get the split option (without =) value to be completed | ||
382 | /** @param[out] valueToBeCompleted : base of the value to be completed | ||
383 | * @param cursorOption : option of the cursor which is currently completed | ||
384 | * @param prevCursorOption : previous option of the cursor | ||
385 | * @return pointer to the Option to be completed or NULL if there is not | ||
386 | */ | ||
387 | 22 | const Option * OptionParser::getSplitOptionValue(std::string & valueToBeCompleted, const std::string & cursorOption, const std::string & prevCursorOption) const{ | |
388 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 16 times.
|
22 | if(prevCursorOption == ""){return NULL;} |
389 | 16 | const Option * op = NULL; | |
390 | 16 | VecMode::const_iterator itMode(p_vecMode.begin()); | |
391 |
6/6✓ Branch 2 taken 46 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 39 times.
✓ Branch 7 taken 16 times.
|
55 | while(itMode != p_vecMode.end() && op == NULL){ |
392 |
3/3✓ Branch 2 taken 39 times.
✓ Branch 4 taken 31 times.
✓ Branch 5 taken 8 times.
|
39 | if(itMode->isCurrentlyParsed()){ //Search only in the mode which is currently parsed |
393 |
1/1✓ Branch 2 taken 31 times.
|
31 | const VecOption & vecOp = itMode->getVecOption(); |
394 | 31 | VecOption::const_iterator itOp(vecOp.begin()); | |
395 |
5/6✓ Branch 2 taken 44 times.
✓ Branch 3 taken 31 times.
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 44 times.
✓ Branch 7 taken 31 times.
|
75 | while(itOp != vecOp.end() && op == NULL){ |
396 |
4/4✓ Branch 2 taken 44 times.
✓ Branch 5 taken 44 times.
✓ Branch 9 taken 44 times.
✓ Branch 12 taken 44 times.
|
44 | std::string fullLongOp("--" + itOp->getLongName()), fullShortOption("-" + itOp->getShortName()); |
397 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 36 times.
|
44 | if(fullLongOp == prevCursorOption){ |
398 | 8 | op = &(*itOp); | |
399 |
1/1✓ Branch 1 taken 8 times.
|
8 | valueToBeCompleted = cursorOption; |
400 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
|
36 | }else if(fullShortOption == prevCursorOption){ |
401 | ✗ | op = &(*itOp); | |
402 | ✗ | valueToBeCompleted = cursorOption; | |
403 | } | ||
404 | 44 | ++itOp; | |
405 | 44 | } | |
406 | } | ||
407 | 39 | ++itMode; | |
408 | } | ||
409 | 16 | return op; | |
410 | } | ||
411 | |||
412 | ///Get the possible options which can be used | ||
413 | /** @param[out] possibleOption : possible options for the bash completion | ||
414 | * @param cursorOption : option of the cursor which is currently completed | ||
415 | */ | ||
416 | 14 | void OptionParser::getPossibleOption(std::string & possibleOption, const std::string & cursorOption) const{ | |
417 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 2 taken 9 times.
|
14 | if(p_vecMode.size() == 1lu){ |
418 | 5 | p_vecMode.front().getPossibleOption(possibleOption, cursorOption); | |
419 | }else{ | ||
420 | 9 | const OptionMode * currentlyParsedMode = getCurrentlyParsedMode(); | |
421 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
|
9 | if(currentlyParsedMode != NULL){ |
422 | 8 | currentlyParsedMode->getPossibleOption(possibleOption, cursorOption); | |
423 | }else{ | ||
424 |
2/2✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
|
4 | for(VecMode::const_iterator itMode = p_vecMode.begin(); itMode != p_vecMode.end(); ++itMode){ |
425 |
1/1✓ Branch 2 taken 3 times.
|
3 | itMode->getPossibleMode(possibleOption, cursorOption); |
426 | } | ||
427 | } | ||
428 | } | ||
429 | 14 | } | |
430 | |||
431 | ///Get the possible other options which can be used | ||
432 | /** @param[out] possibleOption : possible options for the bash completion | ||
433 | * @param cursorOption : option of the cursor which is currently completed | ||
434 | */ | ||
435 | 14 | void OptionParser::getPossibleOtherOption(std::string & possibleOption, const std::string & cursorOption) const{ | |
436 | 14 | std::vector<std::string> vecOtherOption; | |
437 |
2/2✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
|
14 | vecOtherOption.push_back("--help"); |
438 |
2/2✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
|
14 | vecOtherOption.push_back("-h"); |
439 |
2/2✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
|
14 | vecOtherOption.push_back("--version"); |
440 |
2/2✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
|
14 | vecOtherOption.push_back("-v"); |
441 | |||
442 |
2/2✓ Branch 4 taken 56 times.
✓ Branch 5 taken 14 times.
|
70 | for(std::vector<std::string>::iterator it(vecOtherOption.begin()); it != vecOtherOption.end(); ++it){ |
443 |
1/1✓ Branch 2 taken 56 times.
|
56 | std::string optionStr(*it); |
444 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 36 times.
|
56 | if(cursorOption == ""){ |
445 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 4 taken 20 times.
|
20 | possibleOption += optionStr + " "; |
446 | }else{ | ||
447 |
3/3✓ Branch 1 taken 36 times.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 17 times.
|
36 | if(isSameBegining(optionStr, cursorOption)){ |
448 |
2/2✓ Branch 1 taken 19 times.
✓ Branch 4 taken 19 times.
|
19 | possibleOption += optionStr + " "; |
449 | } | ||
450 | } | ||
451 | 56 | } | |
452 | 14 | } | |
453 | |||
454 |