| Directory: | ./ |
|---|---|
| File: | src/OptionParser.cpp |
| Date: | 2024-12-09 15:28:54 |
| 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 |