last_getopt_support.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #pragma once
  2. #include <util/string/cast.h>
  3. #include <util/generic/string.h>
  4. #include <util/generic/vector.h>
  5. #include <util/generic/utility.h>
  6. #include <util/generic/yexception.h>
  7. namespace NLastGetopt {
  8. class TOpt;
  9. class TOpts;
  10. class TOptsParser;
  11. class TOptsParseResult;
  12. /// base of all getopt exceptions
  13. class TException: public yexception {
  14. };
  15. /// TOpts configuration is incorrect
  16. class TConfException: public TException {
  17. };
  18. /// User passed incorrect arguments, parsing failed
  19. /// Note: use `throw TUsageException()` instead of `ythrow TUsageException()` to prevent appearence of stacktrace
  20. /// and location of the `ythrow` statment in error messages.
  21. class TUsageException: public TException {
  22. };
  23. struct IOptHandler {
  24. virtual void HandleOpt(const TOptsParser* parser) = 0;
  25. virtual ~IOptHandler() = default;
  26. };
  27. namespace NPrivate {
  28. template <typename TpFunc>
  29. class THandlerFunctor0
  30. : public IOptHandler {
  31. TpFunc Func_;
  32. public:
  33. THandlerFunctor0(TpFunc func)
  34. : Func_(func)
  35. {
  36. }
  37. void HandleOpt(const TOptsParser*) override {
  38. Func_();
  39. }
  40. };
  41. template <typename TpFunc, typename TpArg = const TOptsParser*>
  42. class THandlerFunctor1
  43. : public IOptHandler {
  44. TpFunc Func_;
  45. const TpArg Def_;
  46. const bool HasDef_;
  47. public:
  48. THandlerFunctor1(TpFunc func)
  49. : Func_(func)
  50. , Def_()
  51. , HasDef_(false)
  52. {
  53. }
  54. template <typename T>
  55. THandlerFunctor1(const TpFunc& func, const T& def)
  56. : Func_(func)
  57. , Def_(def)
  58. , HasDef_(true)
  59. {
  60. }
  61. void HandleOpt(const TOptsParser* parser) override;
  62. };
  63. template <typename TpFunc>
  64. class THandlerFunctor1<TpFunc, const TOptsParser*>
  65. : public IOptHandler {
  66. TpFunc Func_;
  67. public:
  68. THandlerFunctor1(TpFunc func)
  69. : Func_(func)
  70. {
  71. }
  72. void HandleOpt(const TOptsParser* parser) override {
  73. Func_(parser);
  74. }
  75. };
  76. template <typename T, typename TpVal = T>
  77. class TStoreResultFunctor {
  78. private:
  79. T* Target_;
  80. public:
  81. TStoreResultFunctor(T* target)
  82. : Target_(target)
  83. {
  84. }
  85. void operator()(const TpVal& val) {
  86. *Target_ = val;
  87. }
  88. };
  89. template <typename TpTarget, typename TpFunc, typename TpVal = TpTarget>
  90. class TStoreMappedResultFunctor {
  91. private:
  92. TpTarget* Target_;
  93. const TpFunc Func_;
  94. public:
  95. TStoreMappedResultFunctor(TpTarget* target, const TpFunc& func)
  96. : Target_(target)
  97. , Func_(func)
  98. {
  99. }
  100. void operator()(const TpVal& val) {
  101. *Target_ = Func_(val);
  102. }
  103. };
  104. template <typename T, typename TpVal = T>
  105. class TStoreValueFunctor {
  106. T* Target;
  107. const TpVal Value;
  108. public:
  109. template <typename TpArg>
  110. TStoreValueFunctor(T* target, const TpArg& value)
  111. : Target(target)
  112. , Value(value)
  113. {
  114. }
  115. void operator()(const TOptsParser*) {
  116. *Target = Value;
  117. }
  118. };
  119. TString OptToString(char c);
  120. TString OptToString(const TString& longOption);
  121. TString OptToString(const TOpt* opt);
  122. template <typename T>
  123. inline T OptFromStringImpl(const TStringBuf& value) {
  124. return FromString<T>(value);
  125. }
  126. template <>
  127. inline TStringBuf OptFromStringImpl<TStringBuf>(const TStringBuf& value) {
  128. return value;
  129. }
  130. template <>
  131. inline const char* OptFromStringImpl<const char*>(const TStringBuf& value) {
  132. return value.data();
  133. }
  134. template <typename T, typename TSomeOpt>
  135. T OptFromString(const TStringBuf& value, const TSomeOpt opt) {
  136. try {
  137. return OptFromStringImpl<T>(value);
  138. } catch (...) {
  139. throw TUsageException() << "failed to parse opt " << OptToString(opt) << " value " << TString(value).Quote() << ": " << CurrentExceptionMessage();
  140. }
  141. }
  142. // wrapper of FromString<T> that prints nice message about option used
  143. template <typename T, typename TSomeOpt>
  144. T OptFromString(const TStringBuf& value, const TSomeOpt opt);
  145. }
  146. }