last_getopt_opt.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "last_getopt_opt.h"
  2. #include <util/stream/format.h>
  3. #include <util/string/escape.h>
  4. #include <util/generic/ylimits.h>
  5. #include <util/generic/utility.h>
  6. #include <util/generic/algorithm.h>
  7. #include <ctype.h>
  8. namespace NLastGetopt {
  9. static const TStringBuf ExcludedShortNameChars = "= -\t\n";
  10. static const TStringBuf ExcludedLongNameChars = "= \t\n";
  11. bool TOpt::NameIs(const TString& name) const {
  12. for (const auto& next : LongNames_) {
  13. if (next == name)
  14. return true;
  15. }
  16. return false;
  17. }
  18. bool TOpt::CharIs(char c) const {
  19. for (auto next : Chars_) {
  20. if (next == c)
  21. return true;
  22. }
  23. return false;
  24. }
  25. char TOpt::GetChar() const {
  26. if (Chars_.empty())
  27. ythrow TConfException() << "no char for option " << this->ToShortString();
  28. return Chars_.at(0);
  29. }
  30. char TOpt::GetCharOr0() const {
  31. if (Chars_.empty())
  32. return 0;
  33. return GetChar();
  34. }
  35. TString TOpt::GetName() const {
  36. if (LongNames_.empty())
  37. ythrow TConfException() << "no name for option " << this->ToShortString();
  38. return LongNames_.at(0);
  39. }
  40. bool TOpt::IsAllowedShortName(unsigned char c) {
  41. return isprint(c) && TStringBuf::npos == ExcludedShortNameChars.find(c);
  42. }
  43. TOpt& TOpt::AddShortName(unsigned char c) {
  44. if (!IsAllowedShortName(c))
  45. throw TUsageException() << "option char '" << c << "' is not allowed";
  46. Chars_.push_back(c);
  47. return *this;
  48. }
  49. bool TOpt::IsAllowedLongName(const TString& name, unsigned char* out) {
  50. for (size_t i = 0; i != name.size(); ++i) {
  51. const unsigned char c = name[i];
  52. if (!isprint(c) || TStringBuf::npos != ExcludedLongNameChars.find(c)) {
  53. if (nullptr != out)
  54. *out = c;
  55. return false;
  56. }
  57. }
  58. return true;
  59. }
  60. TOpt& TOpt::AddLongName(const TString& name) {
  61. unsigned char c = 0;
  62. if (!IsAllowedLongName(name, &c))
  63. throw TUsageException() << "option char '" << c
  64. << "' in long '" << name << "' is not allowed";
  65. LongNames_.push_back(name);
  66. return *this;
  67. }
  68. namespace NPrivate {
  69. TString OptToString(char c);
  70. TString OptToString(const TString& longOption);
  71. }
  72. TString TOpt::ToShortString() const {
  73. if (!LongNames_.empty())
  74. return NPrivate::OptToString(LongNames_.front());
  75. if (!Chars_.empty())
  76. return NPrivate::OptToString(Chars_.front());
  77. return "?";
  78. }
  79. void TOpt::FireHandlers(const TOptsParser* parser) const {
  80. for (const auto& handler : Handlers_) {
  81. handler->HandleOpt(parser);
  82. }
  83. }
  84. TOpt& TOpt::IfPresentDisableCompletionFor(const TOpt& opt) {
  85. if (opt.GetLongNames()) {
  86. IfPresentDisableCompletionFor(opt.GetName());
  87. } else {
  88. IfPresentDisableCompletionFor(opt.GetChar());
  89. }
  90. return *this;
  91. }
  92. }