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