You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CommandLineParser.cpp 2.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //
  2. // Created by robin on 8/8/15.
  3. //
  4. #include <getopt.h>
  5. #include <iostream>
  6. #include "CommandLineParser.h"
  7. CommandLineParser::CommandLineParser(int argc, char **argv)
  8. : _argc(argc)
  9. , _argv(argv)
  10. {
  11. }
  12. bool CommandLineParser::parse()
  13. {
  14. std::string shortOpts;
  15. option opts[_options.size() + 1];
  16. for (unsigned i = 0; i < _options.size(); ++i)
  17. {
  18. auto opt = _options[i];
  19. shortOpts += opt->getShortName();
  20. if (opt->hasValue())
  21. shortOpts += ":";
  22. opts[i].name = opt->getLongName().c_str();
  23. opts[i].has_arg = opt->hasValue();
  24. opts[i].flag = 0;
  25. opts[i].val = opt->getShortName();
  26. }
  27. opts[_options.size()] = {0, 0, 0, 0};
  28. int option;
  29. extern int optind;
  30. extern char* optarg;
  31. bool valid = true;
  32. while ((option = getopt_long(_argc, _argv, shortOpts.c_str(), opts, 0)) != -1)
  33. {
  34. bool optValid = false;
  35. for (unsigned i = 0; i < _options.size(); ++i)
  36. {
  37. auto opt = _options[i];
  38. if (opt->getShortName() == option)
  39. {
  40. optValid = true;
  41. opt->setIsSet(true);
  42. if (opt->hasValue())
  43. opt->addValue(optarg);
  44. }
  45. }
  46. if (!optValid)
  47. valid = false;
  48. }
  49. return optind == _argc && valid;
  50. }
  51. void CommandLineParser::addOption(CommandLineOption* opt)
  52. {
  53. _options.push_back(opt);
  54. }
  55. int CommandLineParser::showHelp(int status, bool stdErr)
  56. {
  57. auto& out = stdErr ? std::cerr : std::cout;
  58. int longestName = 0;
  59. int longestValue = 0;
  60. for (auto opt : _options) {
  61. if (opt->getLongName().length() > longestName) {
  62. longestName = opt->getLongName().length();
  63. }
  64. std::string value = "<" + opt->getValueName();
  65. if (!opt->getDefaultValue().empty()) {
  66. value += "=" + opt->getDefaultValue();
  67. }
  68. value += ">";
  69. if (value.length() > longestValue) {
  70. longestValue = value.length();
  71. }
  72. }
  73. out << "Options:" << std::endl;
  74. for (auto opt : _options)
  75. {
  76. out << " -" << opt->getShortName() << ", --" << opt->getLongName();
  77. out << std::string(longestName - opt->getLongName().length() + 2, ' ');
  78. if (opt->hasValue())
  79. {
  80. std::string value = "<" + opt->getValueName();
  81. if (!opt->getDefaultValue().empty()) {
  82. value += "=" + opt->getDefaultValue();
  83. }
  84. value += ">";
  85. out << value << std::string(longestValue - value.length() + 2, ' ');
  86. }
  87. else {
  88. out << std::string(longestValue + 2, ' ');
  89. }
  90. out << opt->getDescription() << std::endl;
  91. }
  92. return status;
  93. }