opt.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include "opt.h"
  2. #include <util/system/progname.h>
  3. #include <ctype.h>
  4. using namespace NLastGetopt;
  5. namespace {
  6. struct TOptsNoDefault: public TOpts {
  7. TOptsNoDefault(const TStringBuf& optstring = TStringBuf())
  8. : TOpts(optstring)
  9. {
  10. }
  11. };
  12. }
  13. void Opt::Init(int argc, char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) {
  14. Ions_ = longOptions;
  15. Err = true;
  16. GotError_ = false;
  17. Ind = argc;
  18. Opts_.Reset(new TOptsNoDefault(optString));
  19. for (const Ion* o = longOptions; o != nullptr && o->name != nullptr; ++o) {
  20. TOpt* opt;
  21. if ((unsigned)o->val < 0x80 && isalnum(o->val)) {
  22. opt = &Opts_->CharOption(char(o->val));
  23. opt->AddLongName(o->name);
  24. } else {
  25. Opts_->AddLongOption(o->name);
  26. opt = const_cast<TOpt*>(&Opts_->GetLongOption(o->name));
  27. }
  28. opt->HasArg_ = EHasArg(o->has_arg);
  29. opt->UserValue(o);
  30. }
  31. Opts_->AllowSingleDashForLong_ = longOnly;
  32. Opts_->AllowPlusForLong_ = true;
  33. Opts_->AllowUnknownCharOptions_ = isOpen;
  34. Opts_->AllowUnknownLongOptions_ = false;
  35. OptsParser_.Reset(new TOptsParser(Opts_.Get(), argc, argv));
  36. }
  37. Opt::Opt(int argc, char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) {
  38. Init(argc, argv, optString, longOptions, longOnly, isOpen);
  39. }
  40. Opt::Opt(int argc, const char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) {
  41. Init(argc, (char**)argv, optString, longOptions, longOnly, isOpen);
  42. }
  43. int Opt::Get() {
  44. return Get(nullptr);
  45. }
  46. int Opt::Get(int* longOptionIndex) {
  47. if (GotError_)
  48. return EOF;
  49. Arg = nullptr;
  50. try {
  51. bool r = OptsParser_->Next();
  52. Ind = (int)OptsParser_->Pos_;
  53. if (!r) {
  54. return EOF;
  55. } else {
  56. Arg = (char*)OptsParser_->CurVal();
  57. if (!OptsParser_->CurOpt()) {
  58. // possible if RETURN_IN_ORDER
  59. return 1;
  60. } else {
  61. const Ion* ion = (const Ion*)OptsParser_->CurOpt()->UserValue();
  62. if (longOptionIndex) {
  63. *longOptionIndex = int(ion - Ions_);
  64. }
  65. char c = OptsParser_->CurOpt()->GetCharOr0();
  66. return c != 0 ? c : ion->val;
  67. }
  68. }
  69. } catch (const NLastGetopt::TException&) {
  70. GotError_ = true;
  71. if (Err)
  72. Cerr << CurrentExceptionMessage() << Endl;
  73. return '?';
  74. }
  75. }
  76. void Opt::DummyHelp(IOutputStream& os) {
  77. Opts_->PrintUsage(GetProgramName(), os);
  78. }
  79. int Opt::GetArgC() const {
  80. return (int)OptsParser_->Argc_;
  81. }
  82. const char** Opt::GetArgV() const {
  83. return OptsParser_->Argv_;
  84. }
  85. int opt_get_number(int& argc, char* argv[]) {
  86. int num = -1;
  87. for (int a = 1; a < argc; a++) {
  88. if (*argv[a] == '-' && isdigit((ui8)argv[a][1])) {
  89. char* ne;
  90. num = strtol(argv[a] + 1, &ne, 10);
  91. if (*ne) {
  92. memmove(argv[a] + 1, ne, strlen(ne) + 1);
  93. } else {
  94. for (argc--; a < argc; a++)
  95. argv[a] = argv[a + 1];
  96. }
  97. break;
  98. }
  99. }
  100. return num;
  101. }