| 15 | static THolder<TOptsParser> OptsParser; |
| 16 | |
| 17 | int getopt_long_impl(int argc, char* const* argv, const char* optstring, |
| 18 | const struct option* longopts, int* longindex, bool long_only) { |
| 19 | if (!Opts || optreset == 1) { |
| 20 | optarg = nullptr; |
| 21 | optind = 1; |
| 22 | opterr = 1; |
| 23 | optreset = 0; |
| 24 | Opts.Reset(new TOpts(TOpts::Default(optstring))); |
| 25 | |
| 26 | Opts->AllowSingleDashForLong_ = long_only; |
| 27 | |
| 28 | for (const struct option* o = longopts; o != nullptr && o->name != nullptr; ++o) { |
| 29 | TOpt* opt; |
| 30 | if ((unsigned)o->val < 0x80 && isalnum(o->val)) { |
| 31 | opt = &Opts->CharOption(char(o->val)); |
| 32 | opt->AddLongName(o->name); |
| 33 | } else { |
| 34 | Opts->AddLongOption(o->name); |
| 35 | opt = const_cast<TOpt*>(&Opts->GetLongOption(o->name)); |
| 36 | } |
| 37 | opt->HasArg_ = EHasArg(o->has_arg); |
| 38 | opt->UserValue(o->flag); |
| 39 | } |
| 40 | |
| 41 | OptsParser.Reset(new TOptsParser(&*Opts, argc, (const char**)argv)); |
| 42 | } |
| 43 | |
| 44 | optarg = nullptr; |
| 45 | |
| 46 | try { |
| 47 | if (!OptsParser->Next()) { |
| 48 | return -1; |
| 49 | } else { |
| 50 | optarg = (char*)OptsParser->CurVal(); |
| 51 | optind = (int)OptsParser->Pos_; |
| 52 | if (longindex && OptsParser->CurOpt()) |
| 53 | *longindex = (int)Opts->IndexOf(OptsParser->CurOpt()); |
| 54 | return OptsParser->CurOpt() ? OptsParser->CurOpt()->GetCharOr0() : 1; |
| 55 | } |
| 56 | } catch (const NLastGetopt::TException&) { |
| 57 | return '?'; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | int getopt_long(int argc, char* const* argv, const char* optstring, |
| 62 | const struct option* longopts, int* longindex) { |