Error Args::ParseOptions (Options &options) { StreamString sstr; Error error; struct option *long_options = options.GetLongOptions(); if (long_options == NULL) { error.SetErrorStringWithFormat("Invalid long options.\n"); return error; } for (int i=0; long_options[i].name != NULL; ++i) { if (long_options[i].flag == NULL) { sstr << (char)long_options[i].val; switch (long_options[i].has_arg) { default: case no_argument: break; case required_argument: sstr << ':'; break; case optional_argument: sstr << "::"; break; } } } #ifdef __GLIBC__ optind = 0; #else optreset = 1; optind = 1; #endif int val; while (1) { int long_options_index = -1; val = ::getopt_long(GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options, &long_options_index); if (val == -1) break; // Did we get an error? if (val == '?') { error.SetErrorStringWithFormat("Unknown or ambiguous option.\n"); break; } // The option auto-set itself if (val == 0) continue; ((Options *) &options)->OptionSeen (val); // Lookup the long option index if (long_options_index == -1) { for (int i=0; long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val; ++i) { if (long_options[i].val == val) { long_options_index = i; break; } } } // Call the callback with the option if (long_options_index >= 0) { error = options.SetOptionValue(long_options_index, long_options[long_options_index].has_arg == no_argument ? NULL : optarg); } else { error.SetErrorStringWithFormat("Invalid option with value '%i'.\n", val); } if (error.Fail()) break; } // Update our ARGV now that get options has consumed all the options m_argv.erase(m_argv.begin(), m_argv.begin() + optind); UpdateArgsAfterOptionParsing (); return error; }