--------------------------------------------------------------------------- ^FUNCTION: Options::parse_longopt - parse a long-option ^SYNOPSIS: int Options::parse_longopt(iter, optarg) ^PARAMETERS: OptIter & iter -- option iterator const char * & optarg -- where to store any option-argument ^DESCRIPTION: Parse the next long-option in iter (advancing as necessary). Make sure we update the nextcha
| 931 | // It gets complicated -- follow the comments in the source. |
| 932 | // ^^------------------------------------------------------------------------- |
| 933 | int Options::parse_longopt(OptIter &iter, const char *&optarg) |
| 934 | { |
| 935 | int len = 0, ambiguous = 0; |
| 936 | |
| 937 | listopt = NULLSTR; // reset the list-spec |
| 938 | |
| 939 | if ((optvec == NULL) || (!*optvec)) |
| 940 | return static_cast<signed>(Options::OptRC::ENDOPTS); |
| 941 | |
| 942 | // if a value is supplied in this argv element, get it now |
| 943 | const char *val = strpbrk(nextchar, ":="); |
| 944 | if (val) |
| 945 | { |
| 946 | len = (int)(val - nextchar); |
| 947 | ++val; |
| 948 | } |
| 949 | |
| 950 | // Try to match a known long-option |
| 951 | OptionSpec optspec = match_longopt(nextchar, len, ambiguous); |
| 952 | |
| 953 | // Check for an unknown long-option |
| 954 | if (optspec.isNULL()) |
| 955 | { |
| 956 | // See if this was a short-option in disguise |
| 957 | if ((!ambiguous) && (!(optctrls & static_cast<signed>(Options::OptCtrl::NOGUESSING)))) |
| 958 | { |
| 959 | unsigned save_ctrls = optctrls; |
| 960 | const char *save_nextchar = nextchar; |
| 961 | optctrls |= |
| 962 | (static_cast<signed>(Options::OptCtrl::QUIET) | static_cast<signed>(Options::OptCtrl::NOGUESSING)); |
| 963 | int optchar = parse_opt(iter, optarg); |
| 964 | optctrls = save_ctrls; |
| 965 | if (optchar > 0) |
| 966 | { |
| 967 | return optchar; |
| 968 | } |
| 969 | else |
| 970 | { |
| 971 | nextchar = save_nextchar; |
| 972 | } |
| 973 | } |
| 974 | if (!(optctrls & static_cast<signed>(Options::OptCtrl::QUIET))) |
| 975 | { |
| 976 | cerr << cmdname << ": " << ((ambiguous) ? "ambiguous" : "unknown") << " option " |
| 977 | << ((optctrls & static_cast<signed>(Options::OptCtrl::LONG_ONLY)) ? "-" : "--") << nextchar << "." |
| 978 | << endl; |
| 979 | } |
| 980 | optarg = nextchar; // record the bad option in optarg |
| 981 | nextchar = NULLSTR; // we've exhausted this argument |
| 982 | return (ambiguous) ? static_cast<signed>(Options::OptRC::AMBIGUOUS) : |
| 983 | static_cast<signed>(Options::OptRC::BADKWD); |
| 984 | } |
| 985 | |
| 986 | // If no argument is taken, then leave now |
| 987 | if (optspec.isNoArg()) |
| 988 | { |
| 989 | if ((val) && !(optctrls & static_cast<signed>(Options::OptCtrl::QUIET))) |
| 990 | { |