ygetopt.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "opt.h"
  2. #include "ygetopt.h"
  3. #include <util/generic/string.h>
  4. #include <util/generic/vector.h>
  5. #include <util/generic/yexception.h>
  6. class TGetOpt::TImpl: public TSimpleRefCount<TImpl> {
  7. public:
  8. inline TImpl(int argc, const char* const* argv, const TString& fmt)
  9. : args(argv, argv + argc)
  10. , format(fmt)
  11. {
  12. if (argc == 0) {
  13. ythrow yexception() << "zero argc";
  14. }
  15. }
  16. inline ~TImpl() = default;
  17. TVector<TString> args;
  18. const TString format;
  19. };
  20. class TGetOpt::TIterator::TIterImpl: public TSimpleRefCount<TIterImpl> {
  21. public:
  22. inline TIterImpl(const TGetOpt* parent)
  23. : Args_(parent->Impl_->args)
  24. , ArgsPtrs_(new char*[Args_.size() + 1])
  25. , Format_(parent->Impl_->format)
  26. , OptLet_(0)
  27. , Arg_(nullptr)
  28. {
  29. for (size_t i = 0; i < Args_.size(); ++i) {
  30. ArgsPtrs_.Get()[i] = Args_[i].begin();
  31. }
  32. ArgsPtrs_.Get()[Args_.size()] = nullptr;
  33. Opt_.Reset(new Opt((int)Args_.size(), ArgsPtrs_.Get(), Format_.data()));
  34. }
  35. inline ~TIterImpl() = default;
  36. inline void Next() {
  37. OptLet_ = Opt_->Get();
  38. Arg_ = Opt_->Arg;
  39. }
  40. inline char Key() const noexcept {
  41. return (char)OptLet_;
  42. }
  43. inline const char* Arg() const noexcept {
  44. return Arg_;
  45. }
  46. inline bool AtEnd() const noexcept {
  47. return OptLet_ == EOF;
  48. }
  49. private:
  50. TVector<TString> Args_;
  51. TArrayHolder<char*> ArgsPtrs_;
  52. const TString Format_;
  53. THolder<Opt> Opt_;
  54. int OptLet_;
  55. const char* Arg_;
  56. };
  57. TGetOpt::TIterator::TIterator() noexcept
  58. : Impl_(nullptr)
  59. {
  60. }
  61. TGetOpt::TIterator::TIterator(const TGetOpt* parent)
  62. : Impl_(new TIterImpl(parent))
  63. {
  64. Next();
  65. }
  66. void TGetOpt::TIterator::Next() {
  67. Impl_->Next();
  68. }
  69. char TGetOpt::TIterator::Key() const noexcept {
  70. return Impl_->Key();
  71. }
  72. bool TGetOpt::TIterator::AtEnd() const noexcept {
  73. if (Impl_.Get()) {
  74. return Impl_->AtEnd();
  75. }
  76. return true;
  77. }
  78. const char* TGetOpt::TIterator::Arg() const noexcept {
  79. if (Impl_.Get()) {
  80. return Impl_->Arg();
  81. }
  82. return nullptr;
  83. }
  84. TGetOpt::TGetOpt(int argc, const char* const* argv, const TString& format)
  85. : Impl_(new TImpl(argc, argv, format))
  86. {
  87. }