xref: /freebsd/contrib/ntp/sntp/libopts/find.c (revision a466cc55373fc3cf86837f09da729535b57e69a1)
12b15cb3dSCy Schubert /**
22b15cb3dSCy Schubert  * @file check.c
32b15cb3dSCy Schubert  *
42b15cb3dSCy Schubert  * @brief Hunt for options in the option descriptor list
52b15cb3dSCy Schubert  *
62b15cb3dSCy Schubert  *  This file contains the routines that deal with processing quoted strings
72b15cb3dSCy Schubert  *  into an internal format.
82b15cb3dSCy Schubert  *
92b15cb3dSCy Schubert  * @addtogroup autoopts
102b15cb3dSCy Schubert  * @{
112b15cb3dSCy Schubert  */
122b15cb3dSCy Schubert /*
132b15cb3dSCy Schubert  *  This file is part of AutoOpts, a companion to AutoGen.
142b15cb3dSCy Schubert  *  AutoOpts is free software.
15*a466cc55SCy Schubert  *  AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved
162b15cb3dSCy Schubert  *
172b15cb3dSCy Schubert  *  AutoOpts is available under any one of two licenses.  The license
182b15cb3dSCy Schubert  *  in use must be one of these two and the choice is under the control
192b15cb3dSCy Schubert  *  of the user of the license.
202b15cb3dSCy Schubert  *
212b15cb3dSCy Schubert  *   The GNU Lesser General Public License, version 3 or later
222b15cb3dSCy Schubert  *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
232b15cb3dSCy Schubert  *
242b15cb3dSCy Schubert  *   The Modified Berkeley Software Distribution License
252b15cb3dSCy Schubert  *      See the file "COPYING.mbsd"
262b15cb3dSCy Schubert  *
272b15cb3dSCy Schubert  *  These files have the following sha256 sums:
282b15cb3dSCy Schubert  *
292b15cb3dSCy Schubert  *  8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95  COPYING.gplv3
302b15cb3dSCy Schubert  *  4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b  COPYING.lgplv3
312b15cb3dSCy Schubert  *  13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239  COPYING.mbsd
322b15cb3dSCy Schubert  */
332b15cb3dSCy Schubert 
342b15cb3dSCy Schubert /**
352b15cb3dSCy Schubert  * find the name and name length we are looking for
362b15cb3dSCy Schubert  */
372b15cb3dSCy Schubert static int
parse_opt(char const ** nm_pp,char ** arg_pp,char * buf,size_t bufsz)382b15cb3dSCy Schubert parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz)
392b15cb3dSCy Schubert {
402b15cb3dSCy Schubert     int  res = 0;
412b15cb3dSCy Schubert     char const * p = *nm_pp;
422b15cb3dSCy Schubert     *arg_pp  = NULL;
432b15cb3dSCy Schubert 
442b15cb3dSCy Schubert     for (;;) {
452b15cb3dSCy Schubert         switch (*(p++)) {
462b15cb3dSCy Schubert         case NUL: return res;
472b15cb3dSCy Schubert 
482b15cb3dSCy Schubert         case '=':
492b15cb3dSCy Schubert             memcpy(buf, *nm_pp, (size_t)res);
502b15cb3dSCy Schubert 
512b15cb3dSCy Schubert             buf[res] = NUL;
522b15cb3dSCy Schubert             *nm_pp   = buf;
53*a466cc55SCy Schubert             *arg_pp  = (char *)p;
542b15cb3dSCy Schubert             return res;
552b15cb3dSCy Schubert 
562b15cb3dSCy Schubert         default:
572b15cb3dSCy Schubert             if (++res >= (int)bufsz)
582b15cb3dSCy Schubert                 return -1;
592b15cb3dSCy Schubert         }
602b15cb3dSCy Schubert     }
612b15cb3dSCy Schubert }
622b15cb3dSCy Schubert 
632b15cb3dSCy Schubert /**
642b15cb3dSCy Schubert  *  print out the options that match the given name.
652b15cb3dSCy Schubert  *
662b15cb3dSCy Schubert  * @param pOpts      option data
672b15cb3dSCy Schubert  * @param opt_name   name of option to look for
682b15cb3dSCy Schubert  */
692b15cb3dSCy Schubert static void
opt_ambiguities(tOptions * opts,char const * name,int nm_len)702b15cb3dSCy Schubert opt_ambiguities(tOptions * opts, char const * name, int nm_len)
712b15cb3dSCy Schubert {
722b15cb3dSCy Schubert     char const * const hyph =
732b15cb3dSCy Schubert         NAMED_OPTS(opts) ? "" : LONG_OPT_MARKER;
742b15cb3dSCy Schubert 
752b15cb3dSCy Schubert     tOptDesc * pOD = opts->pOptDesc;
762b15cb3dSCy Schubert     int        idx = 0;
772b15cb3dSCy Schubert 
782b15cb3dSCy Schubert     fputs(zambig_list_msg, stderr);
792b15cb3dSCy Schubert     do  {
802b15cb3dSCy Schubert         if (pOD->pz_Name == NULL)
812b15cb3dSCy Schubert             continue; /* doc option */
822b15cb3dSCy Schubert 
832b15cb3dSCy Schubert         if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0)
842b15cb3dSCy Schubert             fprintf(stderr, zambig_file, hyph, pOD->pz_Name);
852b15cb3dSCy Schubert 
862b15cb3dSCy Schubert         else if (  (pOD->pz_DisableName != NULL)
872b15cb3dSCy Schubert                 && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
882b15cb3dSCy Schubert                 )
892b15cb3dSCy Schubert             fprintf(stderr, zambig_file, hyph, pOD->pz_DisableName);
902b15cb3dSCy Schubert     } while (pOD++, (++idx < opts->optCt));
912b15cb3dSCy Schubert }
922b15cb3dSCy Schubert 
932b15cb3dSCy Schubert /**
942b15cb3dSCy Schubert  *  Determine the number of options that match the name
952b15cb3dSCy Schubert  *
962b15cb3dSCy Schubert  * @param pOpts      option data
972b15cb3dSCy Schubert  * @param opt_name   name of option to look for
982b15cb3dSCy Schubert  * @param nm_len     length of provided name
992b15cb3dSCy Schubert  * @param index      pointer to int for option index
1002b15cb3dSCy Schubert  * @param disable    pointer to bool to mark disabled option
1012b15cb3dSCy Schubert  * @return count of options that match
1022b15cb3dSCy Schubert  */
1032b15cb3dSCy Schubert static int
opt_match_ct(tOptions * opts,char const * name,int nm_len,int * ixp,bool * disable)1042b15cb3dSCy Schubert opt_match_ct(tOptions * opts, char const * name, int nm_len,
1052b15cb3dSCy Schubert              int * ixp, bool * disable)
1062b15cb3dSCy Schubert {
1072b15cb3dSCy Schubert     int   matchCt  = 0;
1082b15cb3dSCy Schubert     int   idx      = 0;
1092b15cb3dSCy Schubert     int   idxLim   = opts->optCt;
1102b15cb3dSCy Schubert     tOptDesc * pOD = opts->pOptDesc;
1112b15cb3dSCy Schubert 
1122b15cb3dSCy Schubert     do  {
1132b15cb3dSCy Schubert         /*
1142b15cb3dSCy Schubert          *  If option disabled or a doc option, skip to next
1152b15cb3dSCy Schubert          */
1162b15cb3dSCy Schubert         if (pOD->pz_Name == NULL)
1172b15cb3dSCy Schubert             continue;
1182b15cb3dSCy Schubert 
1192b15cb3dSCy Schubert         if (  SKIP_OPT(pOD)
1202b15cb3dSCy Schubert            && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT)))
1212b15cb3dSCy Schubert             continue;
1222b15cb3dSCy Schubert 
1232b15cb3dSCy Schubert         if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) {
1242b15cb3dSCy Schubert             /*
1252b15cb3dSCy Schubert              *  IF we have a complete match
1262b15cb3dSCy Schubert              *  THEN it takes priority over any already located partial
1272b15cb3dSCy Schubert              */
1282b15cb3dSCy Schubert             if (pOD->pz_Name[ nm_len ] == NUL) {
1292b15cb3dSCy Schubert                 *ixp = idx;
1302b15cb3dSCy Schubert                 return 1;
1312b15cb3dSCy Schubert             }
1322b15cb3dSCy Schubert         }
1332b15cb3dSCy Schubert 
1342b15cb3dSCy Schubert         /*
1352b15cb3dSCy Schubert          *  IF       there is a disable name
1362b15cb3dSCy Schubert          *     *AND* the option name matches the disable name
1372b15cb3dSCy Schubert          *  THEN ...
1382b15cb3dSCy Schubert          */
1392b15cb3dSCy Schubert         else if (  (pOD->pz_DisableName != NULL)
1402b15cb3dSCy Schubert                 && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
1412b15cb3dSCy Schubert                 )  {
1422b15cb3dSCy Schubert             *disable = true;
1432b15cb3dSCy Schubert 
1442b15cb3dSCy Schubert             /*
1452b15cb3dSCy Schubert              *  IF we have a complete match
1462b15cb3dSCy Schubert              *  THEN it takes priority over any already located partial
1472b15cb3dSCy Schubert              */
1482b15cb3dSCy Schubert             if (pOD->pz_DisableName[ nm_len ] == NUL) {
1492b15cb3dSCy Schubert                 *ixp = idx;
1502b15cb3dSCy Schubert                 return 1;
1512b15cb3dSCy Schubert             }
1522b15cb3dSCy Schubert         }
1532b15cb3dSCy Schubert 
1542b15cb3dSCy Schubert         else
1552b15cb3dSCy Schubert             continue; /* does not match any option */
1562b15cb3dSCy Schubert 
1572b15cb3dSCy Schubert         /*
1582b15cb3dSCy Schubert          *  We found a full or partial match, either regular or disabling.
1592b15cb3dSCy Schubert          *  Remember the index for later.
1602b15cb3dSCy Schubert          */
1612b15cb3dSCy Schubert         *ixp = idx;
1622b15cb3dSCy Schubert         ++matchCt;
1632b15cb3dSCy Schubert 
1642b15cb3dSCy Schubert     } while (pOD++, (++idx < idxLim));
1652b15cb3dSCy Schubert 
1662b15cb3dSCy Schubert     return matchCt;
1672b15cb3dSCy Schubert }
1682b15cb3dSCy Schubert 
1692b15cb3dSCy Schubert /**
1702b15cb3dSCy Schubert  *  Set the option to the indicated option number.
1712b15cb3dSCy Schubert  *
1722b15cb3dSCy Schubert  * @param opts      option data
1732b15cb3dSCy Schubert  * @param arg       option argument (if glued to name)
1742b15cb3dSCy Schubert  * @param idx       option index
1752b15cb3dSCy Schubert  * @param disable   mark disabled option
1762b15cb3dSCy Schubert  * @param st        state about current option
1772b15cb3dSCy Schubert  */
1782b15cb3dSCy Schubert static tSuccess
opt_set(tOptions * opts,char * arg,int idx,bool disable,tOptState * st)1792b15cb3dSCy Schubert opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st)
1802b15cb3dSCy Schubert {
1812b15cb3dSCy Schubert     tOptDesc * pOD = opts->pOptDesc + idx;
1822b15cb3dSCy Schubert 
1832b15cb3dSCy Schubert     if (SKIP_OPT(pOD)) {
1842b15cb3dSCy Schubert         if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
1852b15cb3dSCy Schubert             return FAILURE;
1862b15cb3dSCy Schubert 
1872b15cb3dSCy Schubert         fprintf(stderr, zDisabledErr, opts->pzProgName, pOD->pz_Name);
1882b15cb3dSCy Schubert         if (pOD->pzText != NULL)
1892b15cb3dSCy Schubert             fprintf(stderr, SET_OFF_FMT, pOD->pzText);
1902b15cb3dSCy Schubert         fputc(NL, stderr);
1912b15cb3dSCy Schubert         (*opts->pUsageProc)(opts, EXIT_FAILURE);
1922b15cb3dSCy Schubert         /* NOTREACHED */
1932b15cb3dSCy Schubert         _exit(EXIT_FAILURE); /* to be certain */
1942b15cb3dSCy Schubert     }
1952b15cb3dSCy Schubert 
1962b15cb3dSCy Schubert     /*
1972b15cb3dSCy Schubert      *  IF we found a disablement name,
1982b15cb3dSCy Schubert      *  THEN set the bit in the callers' flag word
1992b15cb3dSCy Schubert      */
2002b15cb3dSCy Schubert     if (disable)
2012b15cb3dSCy Schubert         st->flags |= OPTST_DISABLED;
2022b15cb3dSCy Schubert 
2032b15cb3dSCy Schubert     st->pOD      = pOD;
2042b15cb3dSCy Schubert     st->pzOptArg = arg;
2052b15cb3dSCy Schubert     st->optType  = TOPT_LONG;
2062b15cb3dSCy Schubert 
2072b15cb3dSCy Schubert     return SUCCESS;
2082b15cb3dSCy Schubert }
2092b15cb3dSCy Schubert 
2102b15cb3dSCy Schubert /**
2112b15cb3dSCy Schubert  *  An option was not found.  Check for default option and set it
2122b15cb3dSCy Schubert  *  if there is one.  Otherwise, handle the error.
2132b15cb3dSCy Schubert  *
2142b15cb3dSCy Schubert  * @param opts   option data
2152b15cb3dSCy Schubert  * @param name   name of option to look for
2162b15cb3dSCy Schubert  * @param arg    option argument
2172b15cb3dSCy Schubert  * @param st     state about current option
2182b15cb3dSCy Schubert  *
2192b15cb3dSCy Schubert  * @return success status
2202b15cb3dSCy Schubert  */
2212b15cb3dSCy Schubert static tSuccess
opt_unknown(tOptions * opts,char const * name,char * arg,tOptState * st)2222b15cb3dSCy Schubert opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st)
2232b15cb3dSCy Schubert {
2242b15cb3dSCy Schubert     /*
2252b15cb3dSCy Schubert      *  IF there is no equal sign
2262b15cb3dSCy Schubert      *     *AND* we are using named arguments
2272b15cb3dSCy Schubert      *     *AND* there is a default named option,
2282b15cb3dSCy Schubert      *  THEN return that option.
2292b15cb3dSCy Schubert      */
2302b15cb3dSCy Schubert     if (  (arg == NULL)
2312b15cb3dSCy Schubert        && NAMED_OPTS(opts)
2322b15cb3dSCy Schubert        && (opts->specOptIdx.default_opt != NO_EQUIVALENT)) {
2332b15cb3dSCy Schubert 
2342b15cb3dSCy Schubert         st->pOD      = opts->pOptDesc + opts->specOptIdx.default_opt;
2352b15cb3dSCy Schubert         st->pzOptArg = name;
2362b15cb3dSCy Schubert         st->optType  = TOPT_DEFAULT;
2372b15cb3dSCy Schubert         return SUCCESS;
2382b15cb3dSCy Schubert     }
2392b15cb3dSCy Schubert 
2402b15cb3dSCy Schubert     if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) {
2412b15cb3dSCy Schubert         fprintf(stderr, zIllOptStr, opts->pzProgPath, name);
2422b15cb3dSCy Schubert         (*opts->pUsageProc)(opts, EXIT_FAILURE);
2432b15cb3dSCy Schubert         /* NOTREACHED */
2442b15cb3dSCy Schubert         _exit(EXIT_FAILURE); /* to be certain */
2452b15cb3dSCy Schubert     }
2462b15cb3dSCy Schubert 
2472b15cb3dSCy Schubert     return FAILURE;
2482b15cb3dSCy Schubert }
2492b15cb3dSCy Schubert 
2502b15cb3dSCy Schubert /**
2512b15cb3dSCy Schubert  *  Several options match the provided name.
2522b15cb3dSCy Schubert  *
2532b15cb3dSCy Schubert  * @param opts      option data
2542b15cb3dSCy Schubert  * @param name      name of option to look for
2552b15cb3dSCy Schubert  * @param match_ct  number of matching options
2562b15cb3dSCy Schubert  *
2572b15cb3dSCy Schubert  * @return success status (always FAILURE, if it returns)
2582b15cb3dSCy Schubert  */
2592b15cb3dSCy Schubert static tSuccess
opt_ambiguous(tOptions * opts,char const * name,int match_ct)2602b15cb3dSCy Schubert opt_ambiguous(tOptions * opts, char const * name, int match_ct)
2612b15cb3dSCy Schubert {
2622b15cb3dSCy Schubert     if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) {
2632b15cb3dSCy Schubert         fprintf(stderr, zambig_opt_fmt, opts->pzProgPath, name, match_ct);
2642b15cb3dSCy Schubert         if (match_ct <= 4)
2652b15cb3dSCy Schubert             opt_ambiguities(opts, name, (int)strlen(name));
2662b15cb3dSCy Schubert         (*opts->pUsageProc)(opts, EXIT_FAILURE);
2672b15cb3dSCy Schubert         /* NOTREACHED */
2682b15cb3dSCy Schubert         _exit(EXIT_FAILURE); /* to be certain */
2692b15cb3dSCy Schubert     }
2702b15cb3dSCy Schubert     return FAILURE;
2712b15cb3dSCy Schubert }
2722b15cb3dSCy Schubert 
2732b15cb3dSCy Schubert /*=export_func  optionVendorOption
2742b15cb3dSCy Schubert  * private:
2752b15cb3dSCy Schubert  *
2762b15cb3dSCy Schubert  * what:  Process a vendor option
2772b15cb3dSCy Schubert  * arg:   + tOptions * + pOpts    + program options descriptor +
2782b15cb3dSCy Schubert  * arg:   + tOptDesc * + pOptDesc + the descriptor for this arg +
2792b15cb3dSCy Schubert  *
2802b15cb3dSCy Schubert  * doc:
2812b15cb3dSCy Schubert  *  For POSIX specified utilities, the options are constrained to the options,
2822b15cb3dSCy Schubert  *  @xref{config attributes, Program Configuration}.  AutoOpts clients should
2832b15cb3dSCy Schubert  *  never specify this directly.  It gets referenced when the option
2842b15cb3dSCy Schubert  *  definitions contain a "vendor-opt" attribute.
2852b15cb3dSCy Schubert =*/
2862b15cb3dSCy Schubert void
optionVendorOption(tOptions * pOpts,tOptDesc * pOD)2872b15cb3dSCy Schubert optionVendorOption(tOptions * pOpts, tOptDesc * pOD)
2882b15cb3dSCy Schubert {
2892b15cb3dSCy Schubert     tOptState     opt_st   = OPTSTATE_INITIALIZER(PRESET);
2902b15cb3dSCy Schubert     char const *  vopt_str = pOD->optArg.argString;
2912b15cb3dSCy Schubert 
2922b15cb3dSCy Schubert     if (pOpts <= OPTPROC_EMIT_LIMIT)
2932b15cb3dSCy Schubert         return;
2942b15cb3dSCy Schubert 
2952b15cb3dSCy Schubert     if ((pOD->fOptState & OPTST_RESET) != 0)
2962b15cb3dSCy Schubert         return;
2972b15cb3dSCy Schubert 
2982b15cb3dSCy Schubert     if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0)
2992b15cb3dSCy Schubert         opt_st.flags = OPTST_DEFINED;
3002b15cb3dSCy Schubert 
3012b15cb3dSCy Schubert     if (  ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) == 0)
3022b15cb3dSCy Schubert        || ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st))
3032b15cb3dSCy Schubert        || ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) )
3042b15cb3dSCy Schubert     {
3052b15cb3dSCy Schubert         fprintf(stderr, zIllVendOptStr, pOpts->pzProgName, vopt_str);
3062b15cb3dSCy Schubert         (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
3072b15cb3dSCy Schubert         /* NOTREACHED */
3082b15cb3dSCy Schubert         _exit(EXIT_FAILURE); /* to be certain */
3092b15cb3dSCy Schubert     }
3102b15cb3dSCy Schubert 
3112b15cb3dSCy Schubert     /*
3122b15cb3dSCy Schubert      *  See if we are in immediate handling state.
3132b15cb3dSCy Schubert      */
3142b15cb3dSCy Schubert     if (pOpts->fOptSet & OPTPROC_IMMEDIATE) {
3152b15cb3dSCy Schubert         /*
3162b15cb3dSCy Schubert          *  See if the enclosed option is okay with that state.
3172b15cb3dSCy Schubert          */
3182b15cb3dSCy Schubert         if (DO_IMMEDIATELY(opt_st.flags))
3192b15cb3dSCy Schubert             (void)handle_opt(pOpts, &opt_st);
3202b15cb3dSCy Schubert 
3212b15cb3dSCy Schubert     } else {
3222b15cb3dSCy Schubert         /*
3232b15cb3dSCy Schubert          *  non-immediate direction.
3242b15cb3dSCy Schubert          *  See if the enclosed option is okay with that state.
3252b15cb3dSCy Schubert          */
3262b15cb3dSCy Schubert         if (DO_NORMALLY(opt_st.flags) || DO_SECOND_TIME(opt_st.flags))
3272b15cb3dSCy Schubert             (void)handle_opt(pOpts, &opt_st);
3282b15cb3dSCy Schubert     }
3292b15cb3dSCy Schubert }
3302b15cb3dSCy Schubert 
3312b15cb3dSCy Schubert /**
3322b15cb3dSCy Schubert  *  Find the option descriptor by full name.
3332b15cb3dSCy Schubert  *
3342b15cb3dSCy Schubert  * @param opts      option data
3352b15cb3dSCy Schubert  * @param opt_name  name of option to look for
3362b15cb3dSCy Schubert  * @param state     state about current option
3372b15cb3dSCy Schubert  *
3382b15cb3dSCy Schubert  * @return success status
3392b15cb3dSCy Schubert  */
340*a466cc55SCy Schubert static tSuccess
opt_find_long(tOptions * opts,char const * opt_name,tOptState * state)3412b15cb3dSCy Schubert opt_find_long(tOptions * opts, char const * opt_name, tOptState * state)
3422b15cb3dSCy Schubert {
3432b15cb3dSCy Schubert     char    name_buf[128];
3442b15cb3dSCy Schubert     char *  opt_arg;
3452b15cb3dSCy Schubert     int     nm_len = parse_opt(&opt_name, &opt_arg, name_buf, sizeof(name_buf));
3462b15cb3dSCy Schubert 
3472b15cb3dSCy Schubert     int     idx = 0;
3482b15cb3dSCy Schubert     bool    disable  = false;
3492b15cb3dSCy Schubert     int     ct;
3502b15cb3dSCy Schubert 
3512b15cb3dSCy Schubert     if (nm_len <= 1) {
3522b15cb3dSCy Schubert         if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
3532b15cb3dSCy Schubert             return FAILURE;
3542b15cb3dSCy Schubert 
3552b15cb3dSCy Schubert         fprintf(stderr, zInvalOptName, opts->pzProgName, opt_name);
3562b15cb3dSCy Schubert         (*opts->pUsageProc)(opts, EXIT_FAILURE);
3572b15cb3dSCy Schubert         /* NOTREACHED */
3582b15cb3dSCy Schubert         _exit(EXIT_FAILURE); /* to be certain */
3592b15cb3dSCy Schubert     }
3602b15cb3dSCy Schubert 
3612b15cb3dSCy Schubert     ct = opt_match_ct(opts, opt_name, nm_len, &idx, &disable);
3622b15cb3dSCy Schubert 
3632b15cb3dSCy Schubert     /*
3642b15cb3dSCy Schubert      *  See if we found one match, no matches or multiple matches.
3652b15cb3dSCy Schubert      */
3662b15cb3dSCy Schubert     switch (ct) {
3672b15cb3dSCy Schubert     case 1:  return opt_set(opts, opt_arg, idx, disable, state);
3682b15cb3dSCy Schubert     case 0:  return opt_unknown(opts, opt_name, opt_arg, state);
3692b15cb3dSCy Schubert     default: return opt_ambiguous(opts, opt_name, ct);
3702b15cb3dSCy Schubert     }
3712b15cb3dSCy Schubert }
3722b15cb3dSCy Schubert 
3732b15cb3dSCy Schubert 
3742b15cb3dSCy Schubert /**
3752b15cb3dSCy Schubert  *  Find the short option descriptor for the current option
3762b15cb3dSCy Schubert  *
3772b15cb3dSCy Schubert  * @param pOpts      option data
3782b15cb3dSCy Schubert  * @param optValue   option flag character
3792b15cb3dSCy Schubert  * @param pOptState  state about current option
3802b15cb3dSCy Schubert  */
381*a466cc55SCy Schubert static tSuccess
opt_find_short(tOptions * pOpts,uint_t optValue,tOptState * pOptState)3822b15cb3dSCy Schubert opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState)
3832b15cb3dSCy Schubert {
3842b15cb3dSCy Schubert     tOptDesc * pRes = pOpts->pOptDesc;
3852b15cb3dSCy Schubert     int        ct   = pOpts->optCt;
3862b15cb3dSCy Schubert 
3872b15cb3dSCy Schubert     /*
3882b15cb3dSCy Schubert      *  Search the option list
3892b15cb3dSCy Schubert      */
3902b15cb3dSCy Schubert     do  {
3912b15cb3dSCy Schubert         if (optValue != pRes->optValue)
3922b15cb3dSCy Schubert             continue;
3932b15cb3dSCy Schubert 
3942b15cb3dSCy Schubert         if (SKIP_OPT(pRes)) {
3952b15cb3dSCy Schubert             if (  (pRes->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
3962b15cb3dSCy Schubert                && (pRes->pz_Name != NULL)) {
3972b15cb3dSCy Schubert                 if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0)
3982b15cb3dSCy Schubert                     return FAILURE;
3992b15cb3dSCy Schubert 
4002b15cb3dSCy Schubert                 fprintf(stderr, zDisabledErr, pOpts->pzProgPath, pRes->pz_Name);
4012b15cb3dSCy Schubert                 if (pRes->pzText != NULL)
4022b15cb3dSCy Schubert                     fprintf(stderr, SET_OFF_FMT, pRes->pzText);
4032b15cb3dSCy Schubert                 fputc(NL, stderr);
4042b15cb3dSCy Schubert                 (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
4052b15cb3dSCy Schubert                 /* NOTREACHED */
4062b15cb3dSCy Schubert                 _exit(EXIT_FAILURE); /* to be certain */
4072b15cb3dSCy Schubert             }
4082b15cb3dSCy Schubert             goto short_opt_error;
4092b15cb3dSCy Schubert         }
4102b15cb3dSCy Schubert 
4112b15cb3dSCy Schubert         pOptState->pOD     = pRes;
4122b15cb3dSCy Schubert         pOptState->optType = TOPT_SHORT;
4132b15cb3dSCy Schubert         return SUCCESS;
4142b15cb3dSCy Schubert 
4152b15cb3dSCy Schubert     } while (pRes++, --ct > 0);
4162b15cb3dSCy Schubert 
4172b15cb3dSCy Schubert     /*
4182b15cb3dSCy Schubert      *  IF    the character value is a digit
4192b15cb3dSCy Schubert      *    AND there is a special number option ("-n")
4202b15cb3dSCy Schubert      *  THEN the result is the "option" itself and the
4212b15cb3dSCy Schubert      *       option is the specially marked "number" option.
4222b15cb3dSCy Schubert      */
4232b15cb3dSCy Schubert     if (  IS_DEC_DIGIT_CHAR(optValue)
4242b15cb3dSCy Schubert        && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) {
4252b15cb3dSCy Schubert         pOptState->pOD = \
4262b15cb3dSCy Schubert         pRes           = pOpts->pOptDesc + pOpts->specOptIdx.number_option;
4272b15cb3dSCy Schubert         (pOpts->pzCurOpt)--;
4282b15cb3dSCy Schubert         pOptState->optType = TOPT_SHORT;
4292b15cb3dSCy Schubert         return SUCCESS;
4302b15cb3dSCy Schubert     }
4312b15cb3dSCy Schubert 
4322b15cb3dSCy Schubert  short_opt_error:
4332b15cb3dSCy Schubert 
4342b15cb3dSCy Schubert     /*
4352b15cb3dSCy Schubert      *  IF we are to stop on errors (the default, actually)
4362b15cb3dSCy Schubert      *  THEN call the usage procedure.
4372b15cb3dSCy Schubert      */
4382b15cb3dSCy Schubert     if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
4392b15cb3dSCy Schubert         fprintf(stderr, zIllOptChr, pOpts->pzProgPath, optValue);
4402b15cb3dSCy Schubert         (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
4412b15cb3dSCy Schubert         /* NOTREACHED */
4422b15cb3dSCy Schubert         _exit(EXIT_FAILURE); /* to be certain */
4432b15cb3dSCy Schubert     }
4442b15cb3dSCy Schubert 
4452b15cb3dSCy Schubert     return FAILURE;
4462b15cb3dSCy Schubert }
4472b15cb3dSCy Schubert 
4482b15cb3dSCy Schubert /**
4492b15cb3dSCy Schubert  *  Process option with a required argument.  Long options can either have a
4502b15cb3dSCy Schubert  *  separate command line argument, or an argument attached by the '='
4512b15cb3dSCy Schubert  *  character.  Figure out which.
4522b15cb3dSCy Schubert  *
4532b15cb3dSCy Schubert  *  @param[in,out] opts  the program option descriptor
4542b15cb3dSCy Schubert  *  @param[in,out] o_st  the option processing state
4552b15cb3dSCy Schubert  *  @returns SUCCESS or FAILURE
4562b15cb3dSCy Schubert  */
4572b15cb3dSCy Schubert static tSuccess
get_opt_arg_must(tOptions * opts,tOptState * o_st)4582b15cb3dSCy Schubert get_opt_arg_must(tOptions * opts, tOptState * o_st)
4592b15cb3dSCy Schubert {
4602b15cb3dSCy Schubert     switch (o_st->optType) {
4612b15cb3dSCy Schubert     case TOPT_SHORT:
4622b15cb3dSCy Schubert         /*
4632b15cb3dSCy Schubert          *  See if an arg string follows the flag character
4642b15cb3dSCy Schubert          */
4652b15cb3dSCy Schubert         if (*++(opts->pzCurOpt) == NUL)
4662b15cb3dSCy Schubert             opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx++ ];
4672b15cb3dSCy Schubert         o_st->pzOptArg = opts->pzCurOpt;
4682b15cb3dSCy Schubert         break;
4692b15cb3dSCy Schubert 
4702b15cb3dSCy Schubert     case TOPT_LONG:
4712b15cb3dSCy Schubert         /*
4722b15cb3dSCy Schubert          *  See if an arg string has already been assigned (glued on
4732b15cb3dSCy Schubert          *  with an `=' character)
4742b15cb3dSCy Schubert          */
4752b15cb3dSCy Schubert         if (o_st->pzOptArg == NULL)
4762b15cb3dSCy Schubert             o_st->pzOptArg = opts->origArgVect[ opts->curOptIdx++ ];
4772b15cb3dSCy Schubert         break;
4782b15cb3dSCy Schubert 
4792b15cb3dSCy Schubert     default:
4802b15cb3dSCy Schubert #ifdef DEBUG
4812b15cb3dSCy Schubert         fputs("AutoOpts lib error: option type not selected\n", stderr);
4822b15cb3dSCy Schubert         option_exits(EXIT_FAILURE);
4832b15cb3dSCy Schubert #endif
4842b15cb3dSCy Schubert 
4852b15cb3dSCy Schubert     case TOPT_DEFAULT:
4862b15cb3dSCy Schubert         /*
4872b15cb3dSCy Schubert          *  The option was selected by default.  The current token is
4882b15cb3dSCy Schubert          *  the option argument.
4892b15cb3dSCy Schubert          */
4902b15cb3dSCy Schubert         break;
4912b15cb3dSCy Schubert     }
4922b15cb3dSCy Schubert 
4932b15cb3dSCy Schubert     /*
4942b15cb3dSCy Schubert      *  Make sure we did not overflow the argument list.
4952b15cb3dSCy Schubert      */
4962b15cb3dSCy Schubert     if (opts->curOptIdx > opts->origArgCt) {
4972b15cb3dSCy Schubert         fprintf(stderr, zMisArg, opts->pzProgPath, o_st->pOD->pz_Name);
4982b15cb3dSCy Schubert         return FAILURE;
4992b15cb3dSCy Schubert     }
5002b15cb3dSCy Schubert 
5012b15cb3dSCy Schubert     opts->pzCurOpt = NULL;  /* next time advance to next arg */
5022b15cb3dSCy Schubert     return SUCCESS;
5032b15cb3dSCy Schubert }
5042b15cb3dSCy Schubert 
5052b15cb3dSCy Schubert /**
5062b15cb3dSCy Schubert  * Process an option with an optional argument.  For short options, it looks
5072b15cb3dSCy Schubert  * at the character after the option character, or it consumes the next full
5082b15cb3dSCy Schubert  * argument.  For long options, it looks for an '=' character attachment to
5092b15cb3dSCy Schubert  * the long option name before deciding to take the next command line
5102b15cb3dSCy Schubert  * argument.
5112b15cb3dSCy Schubert  *
5122b15cb3dSCy Schubert  * @param pOpts      the option descriptor
5132b15cb3dSCy Schubert  * @param o_st  a structure for managing the current processing state
5142b15cb3dSCy Schubert  * @returns SUCCESS or does not return
5152b15cb3dSCy Schubert  */
5162b15cb3dSCy Schubert static tSuccess
get_opt_arg_may(tOptions * pOpts,tOptState * o_st)5172b15cb3dSCy Schubert get_opt_arg_may(tOptions * pOpts, tOptState * o_st)
5182b15cb3dSCy Schubert {
5192b15cb3dSCy Schubert     /*
5202b15cb3dSCy Schubert      *  An option argument is optional.
5212b15cb3dSCy Schubert      */
5222b15cb3dSCy Schubert     switch (o_st->optType) {
5232b15cb3dSCy Schubert     case TOPT_SHORT:
5242b15cb3dSCy Schubert         if (*++pOpts->pzCurOpt != NUL)
5252b15cb3dSCy Schubert             o_st->pzOptArg = pOpts->pzCurOpt;
5262b15cb3dSCy Schubert         else {
5272b15cb3dSCy Schubert             char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ];
5282b15cb3dSCy Schubert 
5292b15cb3dSCy Schubert             /*
5302b15cb3dSCy Schubert              *  BECAUSE it is optional, we must make sure
5312b15cb3dSCy Schubert              *  we did not find another flag and that there
5322b15cb3dSCy Schubert              *  is such an argument.
5332b15cb3dSCy Schubert              */
5342b15cb3dSCy Schubert             if ((pzLA == NULL) || (*pzLA == '-'))
5352b15cb3dSCy Schubert                 o_st->pzOptArg = NULL;
5362b15cb3dSCy Schubert             else {
5372b15cb3dSCy Schubert                 pOpts->curOptIdx++; /* argument found */
5382b15cb3dSCy Schubert                 o_st->pzOptArg = pzLA;
5392b15cb3dSCy Schubert             }
5402b15cb3dSCy Schubert         }
5412b15cb3dSCy Schubert         break;
5422b15cb3dSCy Schubert 
5432b15cb3dSCy Schubert     case TOPT_LONG:
5442b15cb3dSCy Schubert         /*
5452b15cb3dSCy Schubert          *  Look for an argument if we don't already have one (glued on
5462b15cb3dSCy Schubert          *  with a `=' character) *AND* we are not in named argument mode
5472b15cb3dSCy Schubert          */
5482b15cb3dSCy Schubert         if (  (o_st->pzOptArg == NULL)
5492b15cb3dSCy Schubert            && (! NAMED_OPTS(pOpts))) {
5502b15cb3dSCy Schubert             char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ];
5512b15cb3dSCy Schubert 
5522b15cb3dSCy Schubert             /*
5532b15cb3dSCy Schubert              *  BECAUSE it is optional, we must make sure
5542b15cb3dSCy Schubert              *  we did not find another flag and that there
5552b15cb3dSCy Schubert              *  is such an argument.
5562b15cb3dSCy Schubert              */
5572b15cb3dSCy Schubert             if ((pzLA == NULL) || (*pzLA == '-'))
5582b15cb3dSCy Schubert                 o_st->pzOptArg = NULL;
5592b15cb3dSCy Schubert             else {
5602b15cb3dSCy Schubert                 pOpts->curOptIdx++; /* argument found */
5612b15cb3dSCy Schubert                 o_st->pzOptArg = pzLA;
5622b15cb3dSCy Schubert             }
5632b15cb3dSCy Schubert         }
5642b15cb3dSCy Schubert         break;
5652b15cb3dSCy Schubert 
5662b15cb3dSCy Schubert     default:
5672b15cb3dSCy Schubert     case TOPT_DEFAULT:
5682b15cb3dSCy Schubert         ao_bug(zbad_default_msg);
5692b15cb3dSCy Schubert     }
5702b15cb3dSCy Schubert 
5712b15cb3dSCy Schubert     /*
5722b15cb3dSCy Schubert      *  After an option with an optional argument, we will
5732b15cb3dSCy Schubert      *  *always* start with the next option because if there
5742b15cb3dSCy Schubert      *  were any characters following the option name/flag,
5752b15cb3dSCy Schubert      *  they would be interpreted as the argument.
5762b15cb3dSCy Schubert      */
5772b15cb3dSCy Schubert     pOpts->pzCurOpt = NULL;
5782b15cb3dSCy Schubert     return SUCCESS;
5792b15cb3dSCy Schubert }
5802b15cb3dSCy Schubert 
5812b15cb3dSCy Schubert /**
5822b15cb3dSCy Schubert  *  Process option that does not have an argument.
5832b15cb3dSCy Schubert  *
5842b15cb3dSCy Schubert  *  @param[in,out] opts  the program option descriptor
5852b15cb3dSCy Schubert  *  @param[in,out] o_st  the option processing state
5862b15cb3dSCy Schubert  *  @returns SUCCESS or FAILURE
5872b15cb3dSCy Schubert  */
5882b15cb3dSCy Schubert static tSuccess
get_opt_arg_none(tOptions * pOpts,tOptState * o_st)5892b15cb3dSCy Schubert get_opt_arg_none(tOptions * pOpts, tOptState * o_st)
5902b15cb3dSCy Schubert {
5912b15cb3dSCy Schubert     /*
5922b15cb3dSCy Schubert      *  No option argument.  Make sure next time around we find
5932b15cb3dSCy Schubert      *  the correct option flag character for short options
5942b15cb3dSCy Schubert      */
5952b15cb3dSCy Schubert     if (o_st->optType == TOPT_SHORT)
5962b15cb3dSCy Schubert         (pOpts->pzCurOpt)++;
5972b15cb3dSCy Schubert 
5982b15cb3dSCy Schubert     /*
5992b15cb3dSCy Schubert      *  It is a long option.  Make sure there was no ``=xxx'' argument
6002b15cb3dSCy Schubert      */
6012b15cb3dSCy Schubert     else if (o_st->pzOptArg != NULL) {
6022b15cb3dSCy Schubert         fprintf(stderr, zNoArg, pOpts->pzProgPath, o_st->pOD->pz_Name);
6032b15cb3dSCy Schubert         return FAILURE;
6042b15cb3dSCy Schubert     }
6052b15cb3dSCy Schubert 
6062b15cb3dSCy Schubert     /*
6072b15cb3dSCy Schubert      *  It is a long option.  Advance to next command line argument.
6082b15cb3dSCy Schubert      */
6092b15cb3dSCy Schubert     else
6102b15cb3dSCy Schubert         pOpts->pzCurOpt = NULL;
611*a466cc55SCy Schubert 
6122b15cb3dSCy Schubert     return SUCCESS;
6132b15cb3dSCy Schubert }
6142b15cb3dSCy Schubert 
6152b15cb3dSCy Schubert /**
6162b15cb3dSCy Schubert  *  Process option.  Figure out whether or not to look for an option argument.
6172b15cb3dSCy Schubert  *
6182b15cb3dSCy Schubert  *  @param[in,out] opts  the program option descriptor
6192b15cb3dSCy Schubert  *  @param[in,out] o_st  the option processing state
6202b15cb3dSCy Schubert  *  @returns SUCCESS or FAILURE
6212b15cb3dSCy Schubert  */
622*a466cc55SCy Schubert static tSuccess
get_opt_arg(tOptions * opts,tOptState * o_st)6232b15cb3dSCy Schubert get_opt_arg(tOptions * opts, tOptState * o_st)
6242b15cb3dSCy Schubert {
6252b15cb3dSCy Schubert     o_st->flags |= (o_st->pOD->fOptState & OPTST_PERSISTENT_MASK);
6262b15cb3dSCy Schubert 
6272b15cb3dSCy Schubert     /*
6282b15cb3dSCy Schubert      * Disabled options and options specified to not have arguments
6292b15cb3dSCy Schubert      * are handled with the "none" procedure.  Otherwise, check the
6302b15cb3dSCy Schubert      * optional flag and call either the "may" or "must" function.
6312b15cb3dSCy Schubert      */
632*a466cc55SCy Schubert     if ((o_st->flags & OPTST_DISABLED) != 0)
6332b15cb3dSCy Schubert         return get_opt_arg_none(opts, o_st);
6342b15cb3dSCy Schubert 
635*a466cc55SCy Schubert     switch (OPTST_GET_ARGTYPE(o_st->flags)) {
636*a466cc55SCy Schubert     case OPARG_TYPE_STATIC:
637*a466cc55SCy Schubert     {
638*a466cc55SCy Schubert         /*
639*a466cc55SCy Schubert          * Propagate the static arg
640*a466cc55SCy Schubert          */
641*a466cc55SCy Schubert         tSuccess res = get_opt_arg_none(opts, o_st);
642*a466cc55SCy Schubert         o_st->pzOptArg = o_st->pOD->optArg.argString;
643*a466cc55SCy Schubert         return res;
644*a466cc55SCy Schubert     }
645*a466cc55SCy Schubert 
646*a466cc55SCy Schubert     case OPARG_TYPE_NONE:
647*a466cc55SCy Schubert         return get_opt_arg_none(opts, o_st);
648*a466cc55SCy Schubert     }
649*a466cc55SCy Schubert 
6502b15cb3dSCy Schubert     if (o_st->flags & OPTST_ARG_OPTIONAL)
6512b15cb3dSCy Schubert         return get_opt_arg_may( opts, o_st);
6522b15cb3dSCy Schubert 
6532b15cb3dSCy Schubert     return get_opt_arg_must(opts, o_st);
6542b15cb3dSCy Schubert }
6552b15cb3dSCy Schubert 
6562b15cb3dSCy Schubert /**
6572b15cb3dSCy Schubert  *  Find the option descriptor for the current option.
6582b15cb3dSCy Schubert  *
6592b15cb3dSCy Schubert  *  @param[in,out] opts  the program option descriptor
6602b15cb3dSCy Schubert  *  @param[in,out] o_st  the option processing state
6612b15cb3dSCy Schubert  *  @returns SUCCESS or FAILURE
6622b15cb3dSCy Schubert  */
663*a466cc55SCy Schubert static tSuccess
find_opt(tOptions * opts,tOptState * o_st)6642b15cb3dSCy Schubert find_opt(tOptions * opts, tOptState * o_st)
6652b15cb3dSCy Schubert {
6662b15cb3dSCy Schubert     /*
6672b15cb3dSCy Schubert      *  IF we are continuing a short option list (e.g. -xyz...)
6682b15cb3dSCy Schubert      *  THEN continue a single flag option.
6692b15cb3dSCy Schubert      *  OTHERWISE see if there is room to advance and then do so.
6702b15cb3dSCy Schubert      */
6712b15cb3dSCy Schubert     if ((opts->pzCurOpt != NULL) && (*opts->pzCurOpt != NUL))
6722b15cb3dSCy Schubert         return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st);
6732b15cb3dSCy Schubert 
6742b15cb3dSCy Schubert     if (opts->curOptIdx >= opts->origArgCt)
6752b15cb3dSCy Schubert         return PROBLEM; /* NORMAL COMPLETION */
6762b15cb3dSCy Schubert 
6772b15cb3dSCy Schubert     opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx ];
6782b15cb3dSCy Schubert 
6792b15cb3dSCy Schubert     /*
6802b15cb3dSCy Schubert      *  IF all arguments must be named options, ...
6812b15cb3dSCy Schubert      */
6822b15cb3dSCy Schubert     if (NAMED_OPTS(opts)) {
6832b15cb3dSCy Schubert         char *      pz  = opts->pzCurOpt;
6842b15cb3dSCy Schubert         int         def;
6852b15cb3dSCy Schubert         tSuccess    res;
6862b15cb3dSCy Schubert         uint16_t *  def_opt;
6872b15cb3dSCy Schubert 
6882b15cb3dSCy Schubert         opts->curOptIdx++;
6892b15cb3dSCy Schubert 
6902b15cb3dSCy Schubert         if (*pz != '-')
6912b15cb3dSCy Schubert             return opt_find_long(opts, pz, o_st);
6922b15cb3dSCy Schubert 
6932b15cb3dSCy Schubert         /*
6942b15cb3dSCy Schubert          *  The name is prefixed with one or more hyphens.  Strip them off
6952b15cb3dSCy Schubert          *  and disable the "default_opt" setting.  Use heavy recasting to
6962b15cb3dSCy Schubert          *  strip off the "const" quality of the "default_opt" field.
6972b15cb3dSCy Schubert          */
6982b15cb3dSCy Schubert         while (*(++pz) == '-')   ;
699276da39aSCy Schubert         def_opt  = VOIDP(&(opts->specOptIdx.default_opt));
7002b15cb3dSCy Schubert         def      = *def_opt;
7012b15cb3dSCy Schubert         *def_opt = NO_EQUIVALENT;
7022b15cb3dSCy Schubert         res      = opt_find_long(opts, pz, o_st);
7032b15cb3dSCy Schubert         *def_opt = (uint16_t)def;
7042b15cb3dSCy Schubert         return res;
7052b15cb3dSCy Schubert     }
7062b15cb3dSCy Schubert 
7072b15cb3dSCy Schubert     /*
7082b15cb3dSCy Schubert      *  Note the kind of flag/option marker
7092b15cb3dSCy Schubert      */
7102b15cb3dSCy Schubert     if (*((opts->pzCurOpt)++) != '-')
7112b15cb3dSCy Schubert         return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
7122b15cb3dSCy Schubert 
7132b15cb3dSCy Schubert     /*
7142b15cb3dSCy Schubert      *  Special hack for a hyphen by itself
7152b15cb3dSCy Schubert      */
7162b15cb3dSCy Schubert     if (*(opts->pzCurOpt) == NUL)
7172b15cb3dSCy Schubert         return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
7182b15cb3dSCy Schubert 
7192b15cb3dSCy Schubert     /*
7202b15cb3dSCy Schubert      *  The current argument is to be processed as an option argument
7212b15cb3dSCy Schubert      */
7222b15cb3dSCy Schubert     opts->curOptIdx++;
7232b15cb3dSCy Schubert 
7242b15cb3dSCy Schubert     /*
7252b15cb3dSCy Schubert      *  We have an option marker.
7262b15cb3dSCy Schubert      *  Test the next character for long option indication
7272b15cb3dSCy Schubert      */
7282b15cb3dSCy Schubert     if (opts->pzCurOpt[0] == '-') {
7292b15cb3dSCy Schubert         if (*++(opts->pzCurOpt) == NUL)
7302b15cb3dSCy Schubert             /*
7312b15cb3dSCy Schubert              *  NORMAL COMPLETION - NOT this arg, but rest are operands
7322b15cb3dSCy Schubert              */
7332b15cb3dSCy Schubert             return PROBLEM;
7342b15cb3dSCy Schubert 
7352b15cb3dSCy Schubert         /*
7362b15cb3dSCy Schubert          *  We do not allow the hyphen to be used as a flag value.
7372b15cb3dSCy Schubert          *  Therefore, if long options are not to be accepted, we punt.
7382b15cb3dSCy Schubert          */
7392b15cb3dSCy Schubert         if ((opts->fOptSet & OPTPROC_LONGOPT) == 0) {
7402b15cb3dSCy Schubert             fprintf(stderr, zIllOptStr, opts->pzProgPath, opts->pzCurOpt-2);
7412b15cb3dSCy Schubert             return FAILURE;
7422b15cb3dSCy Schubert         }
7432b15cb3dSCy Schubert 
7442b15cb3dSCy Schubert         return opt_find_long(opts, opts->pzCurOpt, o_st);
7452b15cb3dSCy Schubert     }
7462b15cb3dSCy Schubert 
7472b15cb3dSCy Schubert     /*
7482b15cb3dSCy Schubert      *  If short options are not allowed, then do long
7492b15cb3dSCy Schubert      *  option processing.  Otherwise the character must be a
7502b15cb3dSCy Schubert      *  short (i.e. single character) option.
7512b15cb3dSCy Schubert      */
7522b15cb3dSCy Schubert     if ((opts->fOptSet & OPTPROC_SHORTOPT) != 0)
7532b15cb3dSCy Schubert         return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st);
7542b15cb3dSCy Schubert 
7552b15cb3dSCy Schubert     return opt_find_long(opts, opts->pzCurOpt, o_st);
7562b15cb3dSCy Schubert }
7572b15cb3dSCy Schubert 
7582b15cb3dSCy Schubert /** @}
7592b15cb3dSCy Schubert  *
7602b15cb3dSCy Schubert  * Local Variables:
7612b15cb3dSCy Schubert  * mode: C
7622b15cb3dSCy Schubert  * c-file-style: "stroustrup"
7632b15cb3dSCy Schubert  * indent-tabs-mode: nil
7642b15cb3dSCy Schubert  * End:
7652b15cb3dSCy Schubert  * end of autoopts/find.c */
766