1ea906c41SOllivier Robert
22b15cb3dSCy Schubert /**
32b15cb3dSCy Schubert * \file putshell.c
4ea906c41SOllivier Robert *
5ea906c41SOllivier Robert * This module will interpret the options set in the tOptions
6ea906c41SOllivier Robert * structure and print them to standard out in a fashion that
7ea906c41SOllivier Robert * will allow them to be interpreted by the Bourne or Korn shells.
82b15cb3dSCy Schubert *
92b15cb3dSCy Schubert * @addtogroup autoopts
102b15cb3dSCy Schubert * @{
11ea906c41SOllivier Robert */
12ea906c41SOllivier Robert /*
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
16ea906c41SOllivier Robert *
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.
20ea906c41SOllivier Robert *
212b15cb3dSCy Schubert * The GNU Lesser General Public License, version 3 or later
222b15cb3dSCy Schubert * See the files "COPYING.lgplv3" and "COPYING.gplv3"
23ea906c41SOllivier Robert *
242b15cb3dSCy Schubert * The Modified Berkeley Software Distribution License
252b15cb3dSCy Schubert * See the file "COPYING.mbsd"
26ea906c41SOllivier Robert *
272b15cb3dSCy Schubert * These files have the following sha256 sums:
28ea906c41SOllivier Robert *
292b15cb3dSCy Schubert * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
302b15cb3dSCy Schubert * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
312b15cb3dSCy Schubert * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
32ea906c41SOllivier Robert */
33ea906c41SOllivier Robert
342b15cb3dSCy Schubert /**
352b15cb3dSCy Schubert * Count the number of bytes required to represent a string as a
362b15cb3dSCy Schubert * compilable string.
372b15cb3dSCy Schubert *
382b15cb3dSCy Schubert * @param[in] scan the text to be rewritten as a C program text string.
392b15cb3dSCy Schubert * @param[in] nl_len the number of bytes used for each embedded newline.
402b15cb3dSCy Schubert *
412b15cb3dSCy Schubert * @returns the count, including the terminating NUL byte.
422b15cb3dSCy Schubert */
432b15cb3dSCy Schubert static size_t
string_size(char const * scan,size_t nl_len)442b15cb3dSCy Schubert string_size(char const * scan, size_t nl_len)
452b15cb3dSCy Schubert {
46ea906c41SOllivier Robert /*
472b15cb3dSCy Schubert * Start by counting the start and end quotes, plus the NUL.
482b15cb3dSCy Schubert */
492b15cb3dSCy Schubert size_t res_ln = 3;
502b15cb3dSCy Schubert
512b15cb3dSCy Schubert for (;;) {
522b15cb3dSCy Schubert char ch = *(scan++);
532b15cb3dSCy Schubert if ((ch >= ' ') && (ch <= '~')) {
542b15cb3dSCy Schubert
552b15cb3dSCy Schubert /*
562b15cb3dSCy Schubert * a backslash allowance for double quotes and baskslashes
572b15cb3dSCy Schubert */
582b15cb3dSCy Schubert res_ln += ((ch == '"') || (ch == '\\')) ? 2 : 1;
592b15cb3dSCy Schubert }
602b15cb3dSCy Schubert
612b15cb3dSCy Schubert /*
622b15cb3dSCy Schubert * When not a normal character, then count the characters
632b15cb3dSCy Schubert * required to represent whatever it is.
642b15cb3dSCy Schubert */
652b15cb3dSCy Schubert else switch (ch) {
662b15cb3dSCy Schubert case NUL:
672b15cb3dSCy Schubert return res_ln;
682b15cb3dSCy Schubert
692b15cb3dSCy Schubert case NL:
702b15cb3dSCy Schubert res_ln += nl_len;
712b15cb3dSCy Schubert break;
722b15cb3dSCy Schubert
732b15cb3dSCy Schubert case HT:
742b15cb3dSCy Schubert case BEL:
752b15cb3dSCy Schubert case BS:
762b15cb3dSCy Schubert case FF:
772b15cb3dSCy Schubert case CR:
782b15cb3dSCy Schubert case VT:
792b15cb3dSCy Schubert res_ln += 2;
802b15cb3dSCy Schubert break;
812b15cb3dSCy Schubert
822b15cb3dSCy Schubert default:
832b15cb3dSCy Schubert res_ln += 4; /* text len for \xNN */
842b15cb3dSCy Schubert }
852b15cb3dSCy Schubert }
862b15cb3dSCy Schubert }
872b15cb3dSCy Schubert
882b15cb3dSCy Schubert /*=export_func optionQuoteString
892b15cb3dSCy Schubert * private:
902b15cb3dSCy Schubert *
912b15cb3dSCy Schubert * what: Print a string as quoted text suitable for a C compiler.
922b15cb3dSCy Schubert * arg: + char const * + text + a block of text to quote +
932b15cb3dSCy Schubert * arg: + char const * + nl + line splice text +
942b15cb3dSCy Schubert *
952b15cb3dSCy Schubert * ret_type: char const *
962b15cb3dSCy Schubert * ret_desc: the allocated input string as a quoted string
972b15cb3dSCy Schubert *
982b15cb3dSCy Schubert * doc:
992b15cb3dSCy Schubert * This is for internal use by autogen and autoopts.
1002b15cb3dSCy Schubert * It takes an input string and produces text the C compiler can process
1012b15cb3dSCy Schubert * to produce an exact copy of the original string.
1022b15cb3dSCy Schubert * The caller must deallocate the result. Standard C strings and
1032b15cb3dSCy Schubert * K&R strings are distinguished by the "nl" string.
1042b15cb3dSCy Schubert =*/
1052b15cb3dSCy Schubert char const *
optionQuoteString(char const * text,char const * nl)1062b15cb3dSCy Schubert optionQuoteString(char const * text, char const * nl)
1072b15cb3dSCy Schubert {
1082b15cb3dSCy Schubert size_t nl_len = strlen(nl);
109*a466cc55SCy Schubert size_t out_sz = string_size(text, nl_len);
1102b15cb3dSCy Schubert char * out;
111*a466cc55SCy Schubert char * res = out = AGALOC(out_sz, "quot str");
112*a466cc55SCy Schubert
1132b15cb3dSCy Schubert *(out++) = '"';
1142b15cb3dSCy Schubert
1152b15cb3dSCy Schubert for (;;) {
1162b15cb3dSCy Schubert unsigned char ch = (unsigned char)*text;
1172b15cb3dSCy Schubert if ((ch >= ' ') && (ch <= '~')) {
1182b15cb3dSCy Schubert if ((ch == '"') || (ch == '\\'))
1192b15cb3dSCy Schubert /*
1202b15cb3dSCy Schubert * We must escape these characters in the output string
1212b15cb3dSCy Schubert */
1222b15cb3dSCy Schubert *(out++) = '\\';
1232b15cb3dSCy Schubert *(out++) = (char)ch;
1242b15cb3dSCy Schubert
1252b15cb3dSCy Schubert } else switch (ch) {
1262b15cb3dSCy Schubert # define add_esc_ch(_ch) { *(out++) = '\\'; *(out++) = (_ch); }
1272b15cb3dSCy Schubert case BEL: add_esc_ch('a'); break;
1282b15cb3dSCy Schubert case BS: add_esc_ch('b'); break;
1292b15cb3dSCy Schubert case HT: add_esc_ch('t'); break;
1302b15cb3dSCy Schubert case VT: add_esc_ch('v'); break;
1312b15cb3dSCy Schubert case FF: add_esc_ch('f'); break;
1322b15cb3dSCy Schubert case CR: add_esc_ch('r'); break;
1332b15cb3dSCy Schubert
1342b15cb3dSCy Schubert case LF:
1352b15cb3dSCy Schubert /*
1362b15cb3dSCy Schubert * Place contiguous new-lines on a single line.
1372b15cb3dSCy Schubert * The current character is a NL, check the next one.
1382b15cb3dSCy Schubert */
1392b15cb3dSCy Schubert while (*++text == NL)
1402b15cb3dSCy Schubert add_esc_ch('n');
1412b15cb3dSCy Schubert
1422b15cb3dSCy Schubert /*
1432b15cb3dSCy Schubert * Insert a splice before starting next line
1442b15cb3dSCy Schubert */
1452b15cb3dSCy Schubert if (*text != NUL) {
1462b15cb3dSCy Schubert memcpy(out, nl, nl_len);
1472b15cb3dSCy Schubert out += nl_len;
1482b15cb3dSCy Schubert
1492b15cb3dSCy Schubert continue; /* text is already at the next character */
1502b15cb3dSCy Schubert }
1512b15cb3dSCy Schubert
1522b15cb3dSCy Schubert add_esc_ch('n');
1532b15cb3dSCy Schubert /* FALLTHROUGH */
1542b15cb3dSCy Schubert
1552b15cb3dSCy Schubert case NUL:
1562b15cb3dSCy Schubert /*
1572b15cb3dSCy Schubert * End of string. Terminate the quoted output. If necessary,
1582b15cb3dSCy Schubert * deallocate the text string. Return the scan resumption point.
1592b15cb3dSCy Schubert */
1602b15cb3dSCy Schubert *(out++) = '"';
161*a466cc55SCy Schubert *(out++) = NUL;
162*a466cc55SCy Schubert #ifndef NDEBUG
163*a466cc55SCy Schubert if ((size_t)(out - res) > out_sz) {
164*a466cc55SCy Schubert fputs(misguess_len, stderr);
165*a466cc55SCy Schubert option_exits(EXIT_FAILURE);
166*a466cc55SCy Schubert }
167*a466cc55SCy Schubert #endif
1682b15cb3dSCy Schubert return res;
1692b15cb3dSCy Schubert
1702b15cb3dSCy Schubert default:
1712b15cb3dSCy Schubert /*
1722b15cb3dSCy Schubert * sprintf is safe here, because we already computed
173*a466cc55SCy Schubert * the amount of space we will be using. Assertion is above.
1742b15cb3dSCy Schubert */
175*a466cc55SCy Schubert out += sprintf(out, MK_STR_OCT_FMT, ch);
1762b15cb3dSCy Schubert }
1772b15cb3dSCy Schubert
1782b15cb3dSCy Schubert text++;
1792b15cb3dSCy Schubert # undef add_esc_ch
1802b15cb3dSCy Schubert }
1812b15cb3dSCy Schubert }
1822b15cb3dSCy Schubert
1832b15cb3dSCy Schubert /**
1842b15cb3dSCy Schubert * Print out escaped apostorophes.
1852b15cb3dSCy Schubert *
1862b15cb3dSCy Schubert * @param[in] str the apostrophies to print
1872b15cb3dSCy Schubert */
1882b15cb3dSCy Schubert static char const *
print_quoted_apostrophes(char const * str)1892b15cb3dSCy Schubert print_quoted_apostrophes(char const * str)
1902b15cb3dSCy Schubert {
1912b15cb3dSCy Schubert while (*str == APOSTROPHE) {
1922b15cb3dSCy Schubert fputs(QUOT_APOS, stdout);
1932b15cb3dSCy Schubert str++;
1942b15cb3dSCy Schubert }
1952b15cb3dSCy Schubert return str;
1962b15cb3dSCy Schubert }
1972b15cb3dSCy Schubert
1982b15cb3dSCy Schubert /**
1992b15cb3dSCy Schubert * Print a single quote (apostrophe quoted) string.
2002b15cb3dSCy Schubert * Other than somersaults for apostrophes, nothing else needs quoting.
2012b15cb3dSCy Schubert *
2022b15cb3dSCy Schubert * @param[in] str the string to print
203ea906c41SOllivier Robert */
204ea906c41SOllivier Robert static void
print_quot_str(char const * str)2052b15cb3dSCy Schubert print_quot_str(char const * str)
206ea906c41SOllivier Robert {
207ea906c41SOllivier Robert /*
208ea906c41SOllivier Robert * Handle empty strings to make the rest of the logic simpler.
209ea906c41SOllivier Robert */
2102b15cb3dSCy Schubert if ((str == NULL) || (*str == NUL)) {
2112b15cb3dSCy Schubert fputs(EMPTY_ARG, stdout);
212ea906c41SOllivier Robert return;
213ea906c41SOllivier Robert }
214ea906c41SOllivier Robert
215ea906c41SOllivier Robert /*
216ea906c41SOllivier Robert * Emit any single quotes/apostrophes at the start of the string and
217ea906c41SOllivier Robert * bail if that is all we need to do.
218ea906c41SOllivier Robert */
2192b15cb3dSCy Schubert str = print_quoted_apostrophes(str);
2202b15cb3dSCy Schubert if (*str == NUL)
221ea906c41SOllivier Robert return;
222ea906c41SOllivier Robert
223ea906c41SOllivier Robert /*
224ea906c41SOllivier Robert * Start the single quote string
225ea906c41SOllivier Robert */
2262b15cb3dSCy Schubert fputc(APOSTROPHE, stdout);
227ea906c41SOllivier Robert for (;;) {
2282b15cb3dSCy Schubert char const * pz = strchr(str, APOSTROPHE);
229ea906c41SOllivier Robert if (pz == NULL)
230ea906c41SOllivier Robert break;
231ea906c41SOllivier Robert
232ea906c41SOllivier Robert /*
233ea906c41SOllivier Robert * Emit the string up to the single quote (apostrophe) we just found.
234ea906c41SOllivier Robert */
2352b15cb3dSCy Schubert (void)fwrite(str, (size_t)(pz - str), (size_t)1, stdout);
236ea906c41SOllivier Robert
237ea906c41SOllivier Robert /*
2382b15cb3dSCy Schubert * Close the current string, emit the apostrophes and re-open the
2392b15cb3dSCy Schubert * string (IFF there is more text to print).
240ea906c41SOllivier Robert */
2412b15cb3dSCy Schubert fputc(APOSTROPHE, stdout);
2422b15cb3dSCy Schubert str = print_quoted_apostrophes(pz);
2432b15cb3dSCy Schubert if (*str == NUL)
244ea906c41SOllivier Robert return;
245ea906c41SOllivier Robert
2462b15cb3dSCy Schubert fputc(APOSTROPHE, stdout);
247ea906c41SOllivier Robert }
248ea906c41SOllivier Robert
249ea906c41SOllivier Robert /*
250ea906c41SOllivier Robert * If we broke out of the loop, we must still emit the remaining text
251ea906c41SOllivier Robert * and then close the single quote string.
252ea906c41SOllivier Robert */
2532b15cb3dSCy Schubert fputs(str, stdout);
2542b15cb3dSCy Schubert fputc(APOSTROPHE, stdout);
255ea906c41SOllivier Robert }
256ea906c41SOllivier Robert
2572b15cb3dSCy Schubert static void
print_enumeration(tOptions * pOpts,tOptDesc * pOD)2582b15cb3dSCy Schubert print_enumeration(tOptions * pOpts, tOptDesc * pOD)
2592b15cb3dSCy Schubert {
2602b15cb3dSCy Schubert uintptr_t e_val = pOD->optArg.argEnum;
2612b15cb3dSCy Schubert printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
2622b15cb3dSCy Schubert
2632b15cb3dSCy Schubert /*
2642b15cb3dSCy Schubert * Convert value to string, print that and restore numeric value.
2652b15cb3dSCy Schubert */
2662b15cb3dSCy Schubert (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
2672b15cb3dSCy Schubert printf(QUOT_ARG_FMT, pOD->optArg.argString);
2682b15cb3dSCy Schubert if (pOD->fOptState & OPTST_ALLOC_ARG)
2692b15cb3dSCy Schubert AGFREE(pOD->optArg.argString);
2702b15cb3dSCy Schubert pOD->optArg.argEnum = e_val;
2712b15cb3dSCy Schubert
2722b15cb3dSCy Schubert printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
2732b15cb3dSCy Schubert }
2742b15cb3dSCy Schubert
2752b15cb3dSCy Schubert static void
print_membership(tOptions * pOpts,tOptDesc * pOD)2762b15cb3dSCy Schubert print_membership(tOptions * pOpts, tOptDesc * pOD)
2772b15cb3dSCy Schubert {
2782b15cb3dSCy Schubert char const * svstr = pOD->optArg.argString;
2792b15cb3dSCy Schubert char const * pz;
2802b15cb3dSCy Schubert uintptr_t val = 1;
2812b15cb3dSCy Schubert printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
2822b15cb3dSCy Schubert (int)(uintptr_t)(pOD->optCookie));
283276da39aSCy Schubert pOD->optCookie = VOIDP(~0UL);
2842b15cb3dSCy Schubert (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
2852b15cb3dSCy Schubert
2862b15cb3dSCy Schubert pz = pOD->optArg.argString;
2872b15cb3dSCy Schubert while (*pz != NUL) {
2882b15cb3dSCy Schubert printf("readonly %s_", pOD->pz_NAME);
2892b15cb3dSCy Schubert pz = SPN_PLUS_N_SPACE_CHARS(pz);
2902b15cb3dSCy Schubert
2912b15cb3dSCy Schubert for (;;) {
2922b15cb3dSCy Schubert int ch = *(pz++);
2932b15cb3dSCy Schubert if (IS_LOWER_CASE_CHAR(ch)) fputc(toupper(ch), stdout);
2942b15cb3dSCy Schubert else if (IS_UPPER_CASE_CHAR(ch)) fputc(ch, stdout);
2952b15cb3dSCy Schubert else if (IS_PLUS_N_SPACE_CHAR(ch)) goto name_done;
2962b15cb3dSCy Schubert else if (ch == NUL) { pz--; goto name_done; }
2972b15cb3dSCy Schubert else fputc('_', stdout);
2982b15cb3dSCy Schubert } name_done:;
2992b15cb3dSCy Schubert printf(SHOW_VAL_FMT, (unsigned long)val);
3002b15cb3dSCy Schubert val <<= 1;
3012b15cb3dSCy Schubert }
3022b15cb3dSCy Schubert
3032b15cb3dSCy Schubert AGFREE(pOD->optArg.argString);
3042b15cb3dSCy Schubert pOD->optArg.argString = svstr;
3052b15cb3dSCy Schubert }
3062b15cb3dSCy Schubert
3072b15cb3dSCy Schubert static void
print_stacked_arg(tOptions * pOpts,tOptDesc * pOD)3082b15cb3dSCy Schubert print_stacked_arg(tOptions * pOpts, tOptDesc * pOD)
3092b15cb3dSCy Schubert {
3102b15cb3dSCy Schubert tArgList * pAL = (tArgList *)pOD->optCookie;
3112b15cb3dSCy Schubert char const ** ppz = pAL->apzArgs;
3122b15cb3dSCy Schubert int ct = pAL->useCt;
3132b15cb3dSCy Schubert
3142b15cb3dSCy Schubert printf(zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct);
3152b15cb3dSCy Schubert
3162b15cb3dSCy Schubert while (--ct >= 0) {
3172b15cb3dSCy Schubert printf(ARG_BY_NUM_FMT, pOpts->pzPROGNAME, pOD->pz_NAME,
3182b15cb3dSCy Schubert pAL->useCt - ct);
3192b15cb3dSCy Schubert print_quot_str(*(ppz++));
3202b15cb3dSCy Schubert printf(EXPORT_ARG_FMT, pOpts->pzPROGNAME, pOD->pz_NAME,
3212b15cb3dSCy Schubert pAL->useCt - ct);
3222b15cb3dSCy Schubert }
3232b15cb3dSCy Schubert }
3242b15cb3dSCy Schubert
3252b15cb3dSCy Schubert /**
3262b15cb3dSCy Schubert * emit the arguments as readily parsed text.
3272b15cb3dSCy Schubert * The program options are set by emitting the shell "set" command.
3282b15cb3dSCy Schubert *
3292b15cb3dSCy Schubert * @param[in] opts the program options structure
3302b15cb3dSCy Schubert */
3312b15cb3dSCy Schubert static void
print_reordering(tOptions * opts)3322b15cb3dSCy Schubert print_reordering(tOptions * opts)
3332b15cb3dSCy Schubert {
3342b15cb3dSCy Schubert unsigned int ix;
3352b15cb3dSCy Schubert
3362b15cb3dSCy Schubert fputs(set_dash, stdout);
3372b15cb3dSCy Schubert
3382b15cb3dSCy Schubert for (ix = opts->curOptIdx;
3392b15cb3dSCy Schubert ix < opts->origArgCt;
3402b15cb3dSCy Schubert ix++) {
3412b15cb3dSCy Schubert fputc(' ', stdout);
3422b15cb3dSCy Schubert print_quot_str(opts->origArgVect[ ix ]);
3432b15cb3dSCy Schubert }
3442b15cb3dSCy Schubert fputs(init_optct, stdout);
3452b15cb3dSCy Schubert }
346ea906c41SOllivier Robert
347ea906c41SOllivier Robert /*=export_func optionPutShell
348ea906c41SOllivier Robert * what: write a portable shell script to parse options
349ea906c41SOllivier Robert * private:
350ea906c41SOllivier Robert * arg: tOptions *, pOpts, the program options descriptor
351ea906c41SOllivier Robert * doc: This routine will emit portable shell script text for parsing
352ea906c41SOllivier Robert * the options described in the option definitions.
353ea906c41SOllivier Robert =*/
354ea906c41SOllivier Robert void
optionPutShell(tOptions * pOpts)355ea906c41SOllivier Robert optionPutShell(tOptions * pOpts)
356ea906c41SOllivier Robert {
357ea906c41SOllivier Robert int optIx = 0;
358ea906c41SOllivier Robert
359ea906c41SOllivier Robert printf(zOptCtFmt, pOpts->curOptIdx-1);
360ea906c41SOllivier Robert
361ea906c41SOllivier Robert do {
362ea906c41SOllivier Robert tOptDesc * pOD = pOpts->pOptDesc + optIx;
363ea906c41SOllivier Robert
3642b15cb3dSCy Schubert if ((pOD->fOptState & OPTST_NO_OUTPUT_MASK) != 0)
365ea906c41SOllivier Robert continue;
366ea906c41SOllivier Robert
367ea906c41SOllivier Robert /*
368ea906c41SOllivier Robert * Equivalence classes are hard to deal with. Where the
369ea906c41SOllivier Robert * option data wind up kind of squishes around. For the purposes
370ea906c41SOllivier Robert * of emitting shell state, they are not recommended, but we'll
371ea906c41SOllivier Robert * do something. I guess we'll emit the equivalenced-to option
372ea906c41SOllivier Robert * at the point in time when the base option is found.
373ea906c41SOllivier Robert */
374ea906c41SOllivier Robert if (pOD->optEquivIndex != NO_EQUIVALENT)
375ea906c41SOllivier Robert continue; /* equivalence to a different option */
376ea906c41SOllivier Robert
377ea906c41SOllivier Robert /*
378ea906c41SOllivier Robert * Equivalenced to a different option. Process the current option
379ea906c41SOllivier Robert * as the equivalenced-to option. Keep the persistent state bits,
380ea906c41SOllivier Robert * but copy over the set-state bits.
381ea906c41SOllivier Robert */
382ea906c41SOllivier Robert if (pOD->optActualIndex != optIx) {
383ea906c41SOllivier Robert tOptDesc * p = pOpts->pOptDesc + pOD->optActualIndex;
384ea906c41SOllivier Robert p->optArg = pOD->optArg;
385ea906c41SOllivier Robert p->fOptState &= OPTST_PERSISTENT_MASK;
386ea906c41SOllivier Robert p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK;
387ea906c41SOllivier Robert printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME);
388ea906c41SOllivier Robert pOD = p;
389ea906c41SOllivier Robert }
390ea906c41SOllivier Robert
391ea906c41SOllivier Robert /*
392ea906c41SOllivier Robert * If the argument type is a set membership bitmask, then we always
393ea906c41SOllivier Robert * emit the thing. We do this because it will always have some sort
394ea906c41SOllivier Robert * of bitmask value and we need to emit the bit values.
395ea906c41SOllivier Robert */
396ea906c41SOllivier Robert if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
3972b15cb3dSCy Schubert print_membership(pOpts, pOD);
398ea906c41SOllivier Robert continue;
399ea906c41SOllivier Robert }
400ea906c41SOllivier Robert
401ea906c41SOllivier Robert /*
402ea906c41SOllivier Robert * IF the option was either specified or it wakes up enabled,
403ea906c41SOllivier Robert * then we will emit information. Otherwise, skip it.
404ea906c41SOllivier Robert * The idea is that if someone defines an option to initialize
405ea906c41SOllivier Robert * enabled, we should tell our shell script that it is enabled.
406ea906c41SOllivier Robert */
407ea906c41SOllivier Robert if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD))
408ea906c41SOllivier Robert continue;
409ea906c41SOllivier Robert
410ea906c41SOllivier Robert /*
411ea906c41SOllivier Robert * Handle stacked arguments
412ea906c41SOllivier Robert */
413ea906c41SOllivier Robert if ( (pOD->fOptState & OPTST_STACKED)
414ea906c41SOllivier Robert && (pOD->optCookie != NULL) ) {
4152b15cb3dSCy Schubert print_stacked_arg(pOpts, pOD);
4162b15cb3dSCy Schubert continue;
417ea906c41SOllivier Robert }
418ea906c41SOllivier Robert
419ea906c41SOllivier Robert /*
420ea906c41SOllivier Robert * If the argument has been disabled,
421ea906c41SOllivier Robert * Then set its value to the disablement string
422ea906c41SOllivier Robert */
4232b15cb3dSCy Schubert if ((pOD->fOptState & OPTST_DISABLED) != 0) {
424ea906c41SOllivier Robert printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME,
425ea906c41SOllivier Robert (pOD->pz_DisablePfx != NULL)
426ea906c41SOllivier Robert ? pOD->pz_DisablePfx : "false");
4272b15cb3dSCy Schubert continue;
4282b15cb3dSCy Schubert }
429ea906c41SOllivier Robert
430ea906c41SOllivier Robert /*
431ea906c41SOllivier Robert * If the argument type is numeric, the last arg pointer
432ea906c41SOllivier Robert * is really the VALUE of the string that was pointed to.
433ea906c41SOllivier Robert */
4342b15cb3dSCy Schubert if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) {
435ea906c41SOllivier Robert printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
436ea906c41SOllivier Robert (int)pOD->optArg.argInt);
4372b15cb3dSCy Schubert continue;
4382b15cb3dSCy Schubert }
439ea906c41SOllivier Robert
440ea906c41SOllivier Robert /*
441ea906c41SOllivier Robert * If the argument type is an enumeration, then it is much
442ea906c41SOllivier Robert * like a text value, except we call the callback function
443ea906c41SOllivier Robert * to emit the value corresponding to the "optArg" number.
444ea906c41SOllivier Robert */
4452b15cb3dSCy Schubert if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) {
4462b15cb3dSCy Schubert print_enumeration(pOpts, pOD);
4472b15cb3dSCy Schubert continue;
448ea906c41SOllivier Robert }
449ea906c41SOllivier Robert
450ea906c41SOllivier Robert /*
451ea906c41SOllivier Robert * If the argument type is numeric, the last arg pointer
452ea906c41SOllivier Robert * is really the VALUE of the string that was pointed to.
453ea906c41SOllivier Robert */
4542b15cb3dSCy Schubert if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) {
455ea906c41SOllivier Robert printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
456ea906c41SOllivier Robert (pOD->optArg.argBool == 0) ? "false" : "true");
4572b15cb3dSCy Schubert continue;
4582b15cb3dSCy Schubert }
459ea906c41SOllivier Robert
460ea906c41SOllivier Robert /*
461ea906c41SOllivier Robert * IF the option has an empty value,
462ea906c41SOllivier Robert * THEN we set the argument to the occurrence count.
463ea906c41SOllivier Robert */
4642b15cb3dSCy Schubert if ( (pOD->optArg.argString == NULL)
4652b15cb3dSCy Schubert || (pOD->optArg.argString[0] == NUL) ) {
466ea906c41SOllivier Robert
467ea906c41SOllivier Robert printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
468ea906c41SOllivier Robert pOD->optOccCt);
4692b15cb3dSCy Schubert continue;
4702b15cb3dSCy Schubert }
471ea906c41SOllivier Robert
472ea906c41SOllivier Robert /*
473ea906c41SOllivier Robert * This option has a text value
474ea906c41SOllivier Robert */
4752b15cb3dSCy Schubert printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
4762b15cb3dSCy Schubert print_quot_str(pOD->optArg.argString);
4772b15cb3dSCy Schubert printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
4782b15cb3dSCy Schubert
479ea906c41SOllivier Robert } while (++optIx < pOpts->presetOptCt );
480ea906c41SOllivier Robert
481ea906c41SOllivier Robert if ( ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
4822b15cb3dSCy Schubert && (pOpts->curOptIdx < pOpts->origArgCt))
4832b15cb3dSCy Schubert print_reordering(pOpts);
4842b15cb3dSCy Schubert
4852b15cb3dSCy Schubert fflush(stdout);
486ea906c41SOllivier Robert }
487ea906c41SOllivier Robert
4882b15cb3dSCy Schubert /** @}
4892b15cb3dSCy Schubert *
490ea906c41SOllivier Robert * Local Variables:
491ea906c41SOllivier Robert * mode: C
492ea906c41SOllivier Robert * c-file-style: "stroustrup"
493ea906c41SOllivier Robert * indent-tabs-mode: nil
494ea906c41SOllivier Robert * End:
495ea906c41SOllivier Robert * end of autoopts/putshell.c */
496