PhoenixPresentation  2.0.0
Set of cmake function to automate presentation generation
OptionParser.cpp
Go to the documentation of this file.
1 /***************************************
2  Auteur : Pierre Aubert
3  Mail : pierre.aubert@lapp.in2p3.fr
4  Licence : CeCILL-C
5 ****************************************/
6 
7 #include "OptionParser.h"
8 
10 
13 OptionParser::OptionParser(bool enableHelpOption, const PString & programVersion)
14  :p_enableHelpOption(enableHelpOption), p_programVersion(programVersion)
15 {
17 }
18 
20 
23  copyOptionParser(other);
24 }
25 
28 
29 }
30 
32 
36  copyOptionParser(other);
37  return *this;
38 }
39 
41 
44 
46 
49 
51 
53 void OptionParser::addMode(const PString & modeName){
54  OptionMode mode(modeName);
57  p_vecMode.push_back(mode);
58  p_currentMode = p_vecMode.size() - 1lu;
59 }
60 
63  p_currentMode = 0lu;
64 }
65 
67 
73 void OptionParser::addOption(const PString & longOption, const PString & shortOption, OptionType::OptionType optionType,
74  bool isRequired, const PString & docString)
75 {
76  OptionValue value;
77  value.setType(optionType);
78  Option option(longOption, shortOption, value, isRequired, docString);
79  option.setIsAllowEmpty(false);
80  p_vecMode[p_currentMode].addOption(option);
81 }
82 
84 
91 void OptionParser::addOption(const PString & longOption, const PString & shortOption, OptionType::OptionType optionType,
92  bool isRequired, bool isAllowEmpty, const PString & docString)
93 {
94  OptionValue value;
95  value.setType(optionType);
96  Option option(longOption, shortOption, value, isRequired, docString);
97  option.setIsAllowEmpty(isAllowEmpty);
98  p_vecMode[p_currentMode].addOption(option);
99 }
100 
102 
110 void OptionParser::addOption(const PString & longOption, const PString & shortOption, OptionType::OptionType optionType,
111  bool isRequired, bool isAllowEmpty, const PVecString & vecPossibleValue, const PString & docString)
112 {
113  OptionValue value;
114  value.setType(optionType);
115  value.setVecPossibleValue(vecPossibleValue);
116  Option option(longOption, shortOption, value, isRequired, docString);
117  option.setIsAllowEmpty(isAllowEmpty);
118  p_vecMode[p_currentMode].addOption(option);
119 }
120 
122 void OptionParser::print() const{
123  if(p_exempleLongOption != "" || p_exempleShortOption != ""){
124  std::cout << "Usage :" << std::endl;
125  if(p_exempleLongOption != ""){std::cout << "\t" << p_exempleLongOption << std::endl;}
126  if(p_exempleShortOption != ""){std::cout << "\t" << p_exempleShortOption << std::endl;}
127  }
128  std::cout << "Parameters :" << std::endl;
129  VecMode::const_iterator it(p_vecMode.begin());
130  it->print();
131  ++it;
132  while(it != p_vecMode.end()){
133  it->print();
134  ++it;
135  }
136 }
137 
139 
142 void OptionParser::parseArgument(int argc, char** argv){
143  ArgParser parser(argc, argv);
144  if(parser.isBashCompletionMode()){
146  }else{
147  parseArgumentNormalUse(parser);
148  }
149 }
150 
152 
155  return p_vecMode[0lu];
156 }
157 
159 
162  return p_vecMode[0lu];
163 }
164 
166 
169 const OptionMode & OptionParser::getMode(const PString & name) const{
170  for(VecMode::const_iterator it(p_vecMode.begin()); it != p_vecMode.end(); ++it){
171  if(it->getName() == name){
172  return *it;
173  }
174  }
175  return getDefaultMode();
176 }
177 
179 
183  for(VecMode::iterator it(p_vecMode.begin()); it != p_vecMode.end(); ++it){
184  if(it->getName() == name){
185  return *it;
186  }
187  }
188  return getDefaultMode();
189 }
190 
192 
195 bool OptionParser::isModeExist(const PString & name) const{
196  bool isSearch(true);
197  VecMode::const_iterator it(p_vecMode.begin());
198  while(isSearch && it != p_vecMode.end()){
199  isSearch &= it->getName() != name;
200  ++it;
201  }
202  return !isSearch;
203 }
204 
206 
209  p_vecMode = other.p_vecMode;
215 }
216 
219  p_currentMode = 0lu;
220  p_currentParserMode = NULL;
221  OptionMode defaultMode;
222  p_vecMode.push_back(defaultMode);
223 }
224 
226 
229  p_currentParserMode = &p_vecMode.front();
230  while(!parser.isEndOfOption()){
231  if(p_enableHelpOption){
232  if(parser.getCurrentOption() == "--help" || parser.getCurrentOption() == "-h"){
233  print();
234  exit(0);
235  }
236  }
237  if(p_programVersion != ""){
238  if(parser.getCurrentOption() == "--version" || parser.getCurrentOption() == "-v"){
239  std::cout << "Program version : " << p_programVersion << std::endl;
240  exit(0);
241  }
242  }
243  OptionMode & currentMode = getParserMode(parser);
244  if(!currentMode.parseOption(parser)){
245  PString modeName(currentMode.getName());
246  PString modeError("");
247  if(modeName != ""){
248  modeError = " in mode '"+modeName+"' ";
249  }
250  throw std::runtime_error("OptionParser::parseArgument : unknown option '"+parser.getCurrentOption()+"'" + modeError);
251  }
252  }
253  if(!checkArgument()){
254  throw std::runtime_error("OptionParser::parseArgument : missing argument");
255  }
256 }
257 
259 
262  //First step, we parse normally the existing arguments
263  PString cursorOption(parser.getCursorOption());
264  PString prevCursorOption(parser.getPrevCursorOption());
265  Option * partialOption = NULL;
266  while(!parser.isEndOfOption()){ //We loop to find the option which has not been parsed well
267  bool isSearch(true);
268  VecMode::iterator itMode = p_vecMode.begin();
269  while(!parser.isEndOfOption() && itMode != p_vecMode.end() && isSearch){
270  isSearch = !itMode->parseOption(parser, partialOption);
271  ++itMode;
272  }
273  if(isSearch){ //If no option matches, we go to the next argument
274  parser.getNextOption();
275  }
276  }
277  //Complete the ongoing option (filename, directory, enum value, etc)
278 // if(partialOption != NULL){ //The option name has no ambiguity but we expect a value
279 // PString possibleValue("");
280 // partialOption->getPossibleValue(possibleValue, cursorOption);
281 // cout << possibleValue << endl;
282 // }else{
283  //Let's get the mode which is currently parsed
284  //If all the options are fine, we have to show the remaning options. That's the following
285  PString possibleValue("");
286  if(completeOptionValue(possibleValue, cursorOption, prevCursorOption)){
287 // saveFileContent("listPossibleValues.txt", possibleValue);
288  std::cout << possibleValue << std::endl;
289  }else{
290  //Then, get the remaning arguments (not parsed yet)
291  PString possibleOption("");
292  getPossibleOption(possibleOption, cursorOption);
293  getPossibleOtherOption(possibleOption, cursorOption);
294 
295 // saveFileContent("listPossibleOption.txt", possibleOption);
296  std::cout << possibleOption << std::endl;
297  }
298 // }
299  exit(0);
300 // La marche a suivre est assez simple
301 // On renvoie une ligne par argument possible
302 // Si il y en a qu'une seule, elle sera ajouté à la fin de la ligne de commande
303 // DONE : mettre en place un méchanisme pour générer le bash qui appellera le programme différemment
304 }
305 
307 
310  bool isArgOk(true);
311  VecMode::const_iterator it(p_vecMode.begin());
312  while(it != p_vecMode.end() && isArgOk){
313  isArgOk = it->checkArgument();
314  ++it;
315  }
316  return isArgOk;
317 }
318 
320 
324  PString currentOption(parser.getCurrentOption());
325  if(isModeExist(currentOption)){
326  OptionMode & mode = getMode(currentOption);
327  p_currentParserMode = &mode;
328  parser.getNextOption();
329  return mode;
330  }else{
331  return *p_currentParserMode;
332  }
333 }
334 
336 
339  const OptionMode * mode = NULL;
340  VecMode::const_iterator it(p_vecMode.begin());
341  while(it != p_vecMode.end() && mode == NULL){
342  if(it->isCurrentlyParsed() && it->getName() != ""){
343  mode = &(*it);
344  }
345  ++it;
346  }
347  return mode;
348 }
349 
351 
355 bool OptionParser::completeOptionValue(PString & possibleValue, const PString & cursorOption, const PString & prevCursorOption) const{
356 // std::cerr << "OptionParser::completeOptionValue : cursorOption = '"<<cursorOption<<"', prevCursorOption = '"<<prevCursorOption<<"'" << std::endl;
357  PString valueToBeCompleted("");
358  //Check is the cursor option starts with a long option (--option=value) because the value can be completed
359  const Option * op = getLongOptionValue(valueToBeCompleted, cursorOption);
360  if(op == NULL){ //Check is the previous option corresponds to an existing option, to complete the value given by the current option
361  op = getSplitOptionValue(valueToBeCompleted, cursorOption, prevCursorOption);
362  }
363  if(op != NULL){
364  op->getPossibleValue(possibleValue, valueToBeCompleted);
365 // std::cerr << "OptionParser::completeOptionValue : possibleValue = '"<<possibleValue<<"'" << std::endl;
366  return true;
367  }
368  return false;
369 }
370 
372 
376 const Option * OptionParser::getLongOptionValue(PString & valueToBeCompleted, const PString & cursorOption) const{
377  if(cursorOption == ""){return NULL;}
378  const Option * op = NULL;
379  VecMode::const_iterator itMode(p_vecMode.begin());
380  while(itMode != p_vecMode.end() && op == NULL){
381  if(itMode->isCurrentlyParsed()){
382  const VecOption & vecOp = itMode->getVecOption();
383  VecOption::const_iterator itOp(vecOp.begin());
384  while(itOp != vecOp.end() && op == NULL){
385  PString fullOp("--" + itOp->getLongName() + "=");
386  if(cursorOption.isSameBegining(fullOp)){
387  op = &(*itOp);
388  valueToBeCompleted = cursorOption.substr(fullOp.size());
389  }
390  ++itOp;
391  }
392  }
393  ++itMode;
394  }
395  return op;
396 }
397 
399 
404 const Option * OptionParser::getSplitOptionValue(PString & valueToBeCompleted, const PString & cursorOption, const PString & prevCursorOption) const{
405  if(prevCursorOption == ""){return NULL;}
406  const Option * op = NULL;
407  VecMode::const_iterator itMode(p_vecMode.begin());
408  while(itMode != p_vecMode.end() && op == NULL){
409  if(itMode->isCurrentlyParsed()){ //Search only in the mode which is currently parsed
410  const VecOption & vecOp = itMode->getVecOption();
411  VecOption::const_iterator itOp(vecOp.begin());
412  while(itOp != vecOp.end() && op == NULL){
413  PString fullLongOp("--" + itOp->getLongName()), fullShortOption("-" + itOp->getShortName());
414  if(fullLongOp == prevCursorOption){
415  op = &(*itOp);
416  valueToBeCompleted = cursorOption;
417  }else if(fullShortOption == prevCursorOption){
418  op = &(*itOp);
419  valueToBeCompleted = cursorOption;
420  }
421  ++itOp;
422  }
423  }
424  ++itMode;
425  }
426  return op;
427 }
428 
430 
433 void OptionParser::getPossibleOption(PString & possibleOption, const PString & cursorOption) const{
434  if(p_vecMode.size() == 1lu){
435  p_vecMode.front().getPossibleOption(possibleOption, cursorOption);
436  }else{
437  const OptionMode * currentlyParsedMode = getCurrentlyParsedMode();
438  if(currentlyParsedMode != NULL){
439  currentlyParsedMode->getPossibleOption(possibleOption, cursorOption);
440  }else{
441  for(VecMode::const_iterator itMode = p_vecMode.begin(); itMode != p_vecMode.end(); ++itMode){
442  itMode->getPossibleMode(possibleOption, cursorOption);
443  }
444  }
445  }
446 }
447 
449 
452 void OptionParser::getPossibleOtherOption(PString & possibleOption, const PString & cursorOption) const{
453  std::vector<PString> vecOtherOption;
454  vecOtherOption.push_back("--help");
455  vecOtherOption.push_back("-h");
456  vecOtherOption.push_back("--version");
457  vecOtherOption.push_back("-v");
458 
459  for(std::vector<PString>::iterator it(vecOtherOption.begin()); it != vecOtherOption.end(); ++it){
460  PString optionStr(*it);
461  if(cursorOption == ""){
462  possibleOption += optionStr + " ";
463  }else{
464  if(optionStr.isSameBegining(cursorOption)){
465  possibleOption += optionStr + " ";
466  }
467  }
468  }
469 }
470 
std::vector< Option > VecOption
Vector of option.
Definition: Option.h:90
std::vector< PString > PVecString
Definition: PString.h:96
Parse the list of arguments passed to a program.
Definition: ArgParser.h:13
const PString & getCurrentOption() const
Get the current option.
Definition: ArgParser.cpp:91
const PString & getCursorOption() const
Get the cursor option given to the program, in bash completion mode.
Definition: ArgParser.cpp:119
bool isBashCompletionMode() const
Say if the program is in bash completion mode.
Definition: ArgParser.cpp:112
void getNextOption()
Move to the next option.
Definition: ArgParser.cpp:77
const PString & getPrevCursorOption() const
Get the previous option before the cursor option.
Definition: ArgParser.cpp:126
bool isEndOfOption() const
Say if is it the end of the options.
Definition: ArgParser.cpp:84
Describe a mode in the program arguments.
Definition: OptionMode.h:13
void getPossibleOption(PString &possibleOption, const PString &cursorOption) const
Get the possible options for the bash completion.
Definition: OptionMode.cpp:225
void setEnableHelpOption(bool b)
Set the attribtue which enables help option.
Definition: OptionMode.cpp:144
void setProgramVersion(const PString &programVersion)
Set the program version.
Definition: OptionMode.cpp:149
bool parseOption(ArgParser &parser)
Parse the options in the current OptionMode.
Definition: OptionMode.cpp:44
const PString & getName() const
Get the name of the OptionMode.
Definition: OptionMode.cpp:154
Parse the options passed to a program.
Definition: OptionParser.h:15
void parseArgument(int argc, char **argv)
Parse the arguments passed to the program.
void addOption(const PString &longOption, const PString &shortOption, OptionType::OptionType optionType, bool isRequired, const PString &docString)
Add an option in the OptionParser.
PString p_exempleLongOption
Usage example with long options.
Definition: OptionParser.h:82
const Option * getSplitOptionValue(PString &valueToBeCompleted, const PString &cursorOption, const PString &prevCursorOption) const
Get the split option (without =) value to be completed.
OptionParser & operator=(const OptionParser &other)
Definition of equal operator of OptionParser.
bool p_enableHelpOption
True to enable automatically the printing of the help option when the program is called with –help or...
Definition: OptionParser.h:86
const OptionMode & getMode(const PString &name) const
Get mode by name.
void setExampleShortOption(const PString &example)
Set the example usage of the program.
void closeMode()
Close the current mode and go back to be default one.
void addMode(const PString &modeName)
Add a mode in the option.
void print() const
Print all the options.
virtual ~OptionParser()
Destructeur of OptionParser.
bool isModeExist(const PString &name) const
Check if the given mode name does exist.
VecMode p_vecMode
Vector of all the defined mode in the OptionParser.
Definition: OptionParser.h:78
void copyOptionParser(const OptionParser &other)
Copy function of OptionParser.
bool completeOptionValue(PString &possibleValue, const PString &cursorOption, const PString &prevCursorOption) const
Complete the possible value of an option (FILENAME, DIRECTORY, FILE_OR_DIR)
bool checkArgument() const
Check the argument of the parser.
void getPossibleOtherOption(PString &possibleOption, const PString &cursorOption) const
Get the possible other options which can be used.
size_t p_currentMode
Index of the current mode in the OptionParser.
Definition: OptionParser.h:80
void getPossibleOption(PString &possibleOption, const PString &cursorOption) const
Get the possible options which can be used.
OptionMode & getParserMode(ArgParser &parser)
Get a mode if it exist.
void initialisationOptionParser()
Initialisation function of the class OptionParser.
OptionMode * p_currentParserMode
Current mode parsed.
Definition: OptionParser.h:76
const Option * getLongOptionValue(PString &valueToBeCompleted, const PString &cursorOption) const
Get the long option value to be completed.
OptionParser(bool enableHelpOption=true, const PString &programVersion="")
Default constructeur of OptionParser.
const OptionMode * getCurrentlyParsedMode() const
Get the currently parsed OptionMode.
void setExampleLongOption(const PString &example)
Set the example usage of the program.
PString p_programVersion
Program version to be printed on –version or -v option.
Definition: OptionParser.h:88
PString p_exempleShortOption
Usage example with short options.
Definition: OptionParser.h:84
void parseArgumentNormalUse(ArgParser &parser)
Classical argument parsing mode.
const OptionMode & getDefaultMode() const
Get default mode.
void parseArgumentBashCompletion(ArgParser &parser)
Bash completion argument parsing mode.
Describe the value of an option passed to a program.
Definition: OptionValue.h:16
void setVecPossibleValue(const PVecString &vecPossibleValue)
Set the vector of possible values.
void setType(OptionType::OptionType type)
Set the type of the OptionValue.
Describes an option passed to a program.
Definition: Option.h:14
void setIsAllowEmpty(bool isAllowEmpty)
Say if the option can be empty or not.
Definition: Option.cpp:184
void getPossibleValue(PString &possibleValue, const PString &cursorOption) const
Complete the possible values of the Option.
Definition: Option.cpp:315
Extends the std::string.
Definition: PString.h:16
bool isSameBegining(const PString &beginStr) const
Say if the current PString has the same begining of beginStr.
Definition: PString.cpp:306