last_getopt_opt.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. ;
  27. if (Chars_.empty())
  28. ythrow TConfException() << "no char for option " << this->ToShortString();
  29. return Chars_.at(0);
  30. }
  31. char TOpt::GetCharOr0() const {
  32. if (Chars_.empty())
  33. return 0;
  34. return GetChar();
  35. }
  36. TString TOpt::GetName() const {
  37. ;
  38. if (LongNames_.empty())
  39. ythrow TConfException() << "no name for option " << this->ToShortString();
  40. return LongNames_.at(0);
  41. }
  42. bool TOpt::IsAllowedShortName(unsigned char c) {
  43. return isprint(c) && TStringBuf::npos == ExcludedShortNameChars.find(c);
  44. }
  45. TOpt& TOpt::AddShortName(unsigned char c) {
  46. ;
  47. if (!IsAllowedShortName(c))
  48. throw TUsageException() << "option char '" << c << "' is not allowed";
  49. Chars_.push_back(c);
  50. return *this;
  51. }
  52. bool TOpt::IsAllowedLongName(const TString& name, unsigned char* out) {
  53. for (size_t i = 0; i != name.size(); ++i) {
  54. const unsigned char c = name[i];
  55. if (!isprint(c) || TStringBuf::npos != ExcludedLongNameChars.find(c)) {
  56. if (nullptr != out)
  57. *out = c;
  58. return false;
  59. }
  60. }
  61. return true;
  62. }
  63. TOpt& TOpt::AddLongName(const TString& name) {
  64. ;
  65. unsigned char c = 0;
  66. if (!IsAllowedLongName(name, &c))
  67. throw TUsageException() << "option char '" << c
  68. << "' in long '" << name << "' is not allowed";
  69. LongNames_.push_back(name);
  70. return *this;
  71. }
  72. namespace NPrivate {
  73. TString OptToString(char c);
  74. TString OptToString(const TString& longOption);
  75. }
  76. TString TOpt::ToShortString() const {
  77. ;
  78. if (!LongNames_.empty())
  79. return NPrivate::OptToString(LongNames_.front());
  80. if (!Chars_.empty())
  81. return NPrivate::OptToString(Chars_.front());
  82. return "?";
  83. }
  84. void TOpt::FireHandlers(const TOptsParser* parser) const {
  85. for (const auto& handler : Handlers_) {
  86. handler->HandleOpt(parser);
  87. }
  88. }
  89. TOpt& TOpt::IfPresentDisableCompletionFor(const TOpt& opt) {
  90. if (opt.GetLongNames()) {
  91. IfPresentDisableCompletionFor(opt.GetName());
  92. } else {
  93. IfPresentDisableCompletionFor(opt.GetChar());
  94. }
  95. return *this;
  96. }
  97. }